Completed
Push — v3.0 ( 23635d...e28df5 )
by Samir
23s
created
astpp/application/libraries/html2pdf/_class/parsingCss.class.php 1 patch
Indentation   +1797 added lines, -1797 removed lines patch added patch discarded remove patch
@@ -11,1802 +11,1802 @@
 block discarded – undo
11 11
 
12 12
 class HTML2PDF_parsingCss
13 13
 {
14
-    /**
15
-     * reference to the pdf object
16
-     * @var TCPDF
17
-     */
18
-    protected $_pdf         = null;
19
-
20
-    protected $_htmlColor   = array(); // list of the HTML colors
21
-    protected $_onlyLeft    = false;   // flag if we are in a sub html => only "text-align:left" is used
22
-    protected $_defaultFont = null;    // default font to use if the asked font does not exist
23
-
24
-    public    $value        = array(); // current values
25
-    public    $css          = array(); // css values
26
-    public    $cssKeys      = array(); // css key, for the execution order
27
-    public    $table        = array(); // level history
28
-
29
-    /**
30
-     * Constructor
31
-     *
32
-     * @param  &HTML2PDF_myPdf reference to the PDF $object
33
-     * @access public
34
-     */
35
-    public function __construct(&$pdf)
36
-    {
37
-        $this->_init();
38
-        $this->setPdfParent($pdf);
39
-    }
40
-
41
-    /**
42
-     * Set the HTML2PDF parent object
43
-     *
44
-     * @param  &HTML2PDF reference to the HTML2PDF parent $object
45
-     * @access public
46
-     */
47
-    public function setPdfParent(&$pdf)
48
-    {
49
-        $this->_pdf = &$pdf;
50
-    }
51
-
52
-    /**
53
-     * Inform that we want only "test-align:left" because we are in a sub HTML
54
-     *
55
-     * @access public
56
-     */
57
-    public function setOnlyLeft()
58
-    {
59
-        $this->value['text-align'] = 'left';
60
-        $this->_onlyLeft = true;
61
-    }
62
-
63
-    /**
64
-     * Get the vales of the parent, if exist
65
-     *
66
-     * @return array CSS values
67
-     * @access public
68
-     */
69
-    public function getOldValues()
70
-    {
71
-        return isset($this->table[count($this->table)-1]) ? $this->table[count($this->table)-1] : $this->value;
72
-    }
73
-
74
-    /**
75
-    * define the Default Font to use, if the font does not exist, or if no font asked
76
-    *
77
-    * @param  string  default font-family. If null : Arial for no font asked, and error fot ont does not exist
78
-    * @return string  old default font-family
79
-    * @access public
80
-    */
81
-    public function setDefaultFont($default = null)
82
-    {
83
-        $old = $this->_defaultFont;
84
-        $this->_defaultFont = $default;
85
-        if ($default) $this->value['font-family'] = $default;
86
-        return $old;
87
-    }
88
-
89
-     /**
90
-     * Init the object
91
-     *
92
-     * @access protected
93
-     */
94
-    protected function _init()
95
-    {
96
-        // get the Web Colors from TCPDF
97
-        require(K_PATH_MAIN.'htmlcolors.php');
98
-        $this->_htmlColor = $webcolor;
99
-
100
-        // init the Style
101
-        $this->table = array();
102
-        $this->value = array();
103
-        $this->initStyle();
104
-
105
-        // Init the styles without legacy
106
-        $this->resetStyle();
107
-    }
108
-
109
-    /**
110
-     * Init the CSS Style
111
-     *
112
-     * @access public
113
-     */
114
-    public function initStyle()
115
-    {
116
-        $this->value['id_tag']       = 'body';        // tag name
117
-        $this->value['id_name']          = null;         // tag - attribute name
118
-        $this->value['id_id']            = null;         // tag - attribute id
119
-        $this->value['id_class']         = null;         // tag - attribute class
120
-        $this->value['id_lst']           = array('*');   // tag - list of legacy
121
-        $this->value['mini-size']        = 1.;           // specific size report for sup, sub
122
-        $this->value['mini-decal']       = 0;            // specific position report for sup, sub
123
-        $this->value['font-family']      = 'Arial';
124
-        $this->value['font-bold']        = false;
125
-        $this->value['font-italic']      = false;
126
-        $this->value['font-underline']   = false;
127
-        $this->value['font-overline']    = false;
128
-        $this->value['font-linethrough'] = false;
129
-        $this->value['text-transform']   = 'none';
130
-        $this->value['font-size']        = $this->convertToMM('10pt');
131
-        $this->value['text-indent']      = 0;
132
-        $this->value['text-align']       = 'left';
133
-        $this->value['vertical-align']   = 'middle';
134
-        $this->value['line-height']      = 'normal';
135
-
136
-        $this->value['position']         = null;
137
-        $this->value['x']                = null;
138
-        $this->value['y']                = null;
139
-        $this->value['width']            = 0;
140
-        $this->value['height']           = 0;
141
-        $this->value['top']              = null;
142
-        $this->value['right']            = null;
143
-        $this->value['bottom']           = null;
144
-        $this->value['left']             = null;
145
-        $this->value['float']            = null;
146
-        $this->value['display']          = null;
147
-        $this->value['rotate']           = null;
148
-        $this->value['overflow']         = 'visible';
149
-
150
-        $this->value['color']            = array(0, 0, 0);
151
-        $this->value['background']       = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
152
-        $this->value['border']           = array();
153
-        $this->value['padding']          = array();
154
-        $this->value['margin']           = array();
155
-        $this->value['margin-auto']      = false;
156
-
157
-        $this->value['list-style-type']  = '';
158
-        $this->value['list-style-image'] = '';
159
-
160
-        $this->value['xc'] = null;
161
-        $this->value['yc'] = null;
162
-    }
163
-
164
-    /**
165
-     * Init the CSS Style without legacy
166
-     *
167
-     * @param  string  tag name
168
-     * @access public
169
-     */
170
-    public function resetStyle($tagName = '')
171
-    {
172
-        // prepare somme values
173
-        $border = $this->readBorder('solid 1px #000000');
174
-        $units = array(
175
-            '1px' => $this->convertToMM('1px'),
176
-            '5px' => $this->convertToMM('5px'),
177
-        );
178
-
179
-
180
-        // prepare the Collapse attribute
181
-        $collapse = isset($this->value['border']['collapse']) ? $this->value['border']['collapse'] : false;
182
-        if (!in_array($tagName, array('tr', 'td', 'th', 'thead', 'tbody', 'tfoot'))) $collapse = false;
183
-
184
-        // set the global css values
185
-        $this->value['position']   = null;
186
-        $this->value['x']          = null;
187
-        $this->value['y']          = null;
188
-        $this->value['width']      = 0;
189
-        $this->value['height']     = 0;
190
-        $this->value['top']        = null;
191
-        $this->value['right']      = null;
192
-        $this->value['bottom']     = null;
193
-        $this->value['left']       = null;
194
-        $this->value['float']      = null;
195
-        $this->value['display']    = null;
196
-        $this->value['rotate']     = null;
197
-        $this->value['overflow']   = 'visible';
198
-        $this->value['background'] = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
199
-        $this->value['border']     = array(
200
-            't' => $this->readBorder('none'),
201
-            'r' => $this->readBorder('none'),
202
-            'b' => $this->readBorder('none'),
203
-            'l' => $this->readBorder('none'),
204
-            'radius' => array(
205
-                'tl' => array(0, 0),
206
-                'tr' => array(0, 0),
207
-                'br' => array(0, 0),
208
-                'bl' => array(0, 0)
209
-            ),
210
-            'collapse' => $collapse,
211
-        );
212
-
213
-        // specific values for some tags
214
-        if (!in_array($tagName, array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) {
215
-            $this->value['margin'] = array('t'=>0,'r'=>0,'b'=>0,'l'=>0);
216
-        }
217
-
218
-        if (in_array($tagName, array('input', 'select', 'textarea'))) {
219
-            $this->value['border']['t'] = null;
220
-            $this->value['border']['r'] = null;
221
-            $this->value['border']['b'] = null;
222
-            $this->value['border']['l'] = null;
223
-        }
224
-
225
-        if ($tagName=='p') {
226
-            $this->value['margin']['t'] = null;
227
-            $this->value['margin']['b'] = null;
228
-        }
229
-        if ($tagName=='blockquote') {
230
-            $this->value['margin']['t'] = 3;
231
-            $this->value['margin']['r'] = 3;
232
-            $this->value['margin']['b'] = 3;
233
-            $this->value['margin']['l'] = 6;
234
-        }
235
-        $this->value['margin-auto'] = false;
236
-
237
-        if (in_array($tagName, array('blockquote', 'div', 'fieldset'))) {
238
-            $this->value['vertical-align'] = 'top';
239
-        }
240
-
241
-        if (in_array($tagName, array('fieldset', 'legend'))) {
242
-            $this->value['border'] = array(
243
-                't' => $border,
244
-                'r' => $border,
245
-                'b' => $border,
246
-                'l' => $border,
247
-                'radius' => array(
248
-                    'tl' => array($units['5px'], $units['5px']),
249
-                    'tr' => array($units['5px'], $units['5px']),
250
-                    'br' => array($units['5px'], $units['5px']),
251
-                    'bl' => array($units['5px'], $units['5px'])
252
-                ),
253
-                'collapse' => false,
254
-            );
255
-        }
256
-
257
-        if (in_array($tagName, array('ul', 'li'))) {
258
-            $this->value['list-style-type']  = '';
259
-            $this->value['list-style-image'] = '';
260
-        }
261
-
262
-        if (!in_array($tagName, array('tr', 'td'))) {
263
-            $this->value['padding'] = array(
264
-                't' => 0,
265
-                'r' => 0,
266
-                'b' => 0,
267
-                'l' => 0
268
-            );
269
-        } else {
270
-            $this->value['padding'] = array(
271
-                't' => $units['1px'],
272
-                'r' => $units['1px'],
273
-                'b' => $units['1px'],
274
-                'l' => $units['1px']
275
-            );
276
-        }
277
-
278
-        if ($tagName=='hr') {
279
-            $this->value['border'] = array(
280
-                't' => $border,
281
-                'r' => $border,
282
-                'b' => $border,
283
-                'l' => $border,
284
-                'radius' => array(
285
-                    'tl' => array(0, 0),
286
-                    'tr' => array(0, 0),
287
-                    'br' => array(0, 0),
288
-                    'bl' => array(0, 0)
289
-                ),
290
-                'collapse' => false,
291
-            );
292
-            $this->convertBackground('#FFFFFF', $this->value['background']);
293
-        }
294
-
295
-        $this->value['xc'] = null;
296
-        $this->value['yc'] = null;
297
-    }
298
-
299
-    /**
300
-     * Init the PDF Font
301
-     *
302
-     * @access public
303
-     */
304
-    public function fontSet()
305
-    {
306
-        $family = strtolower($this->value['font-family']);
307
-
308
-        $b = ($this->value['font-bold']        ? 'B' : '');
309
-        $i = ($this->value['font-italic']      ? 'I' : '');
310
-        $u = ($this->value['font-underline']   ? 'U' : '');
311
-        $d = ($this->value['font-linethrough'] ? 'D' : '');
312
-        $o = ($this->value['font-overline']    ? 'O' : '');
313
-
314
-        // font style
315
-        $style = $b.$i;
316
-
317
-        if ($this->_defaultFont) {
318
-            if($family=='arial')
319
-                $family='helvetica';
320
-            elseif($family=='symbol' || $family=='zapfdingbats')
321
-                $style='';
322
-
323
-            $fontkey = $family.$style;
324
-            if (!$this->_pdf->isLoadedFont($fontkey))
325
-                $family = $this->_defaultFont;
326
-        }
327
-
328
-        if($family=='arial')
329
-            $family='helvetica';
330
-        elseif($family=='symbol' || $family=='zapfdingbats')
331
-            $style='';
332
-
333
-        // complete style
334
-        $style.= $u.$d.$o;
335
-
336
-        // size : mm => pt
337
-        $size = $this->value['font-size'];
338
-        $size = 72 * $size / 25.4;
339
-
340
-        // apply the font
341
-        $this->_pdf->SetFont($family, $style, $this->value['mini-size']*$size);
342
-        $this->_pdf->setTextColorArray($this->value['color']);
343
-        if ($this->value['background']['color'])
344
-            $this->_pdf->setFillColorArray($this->value['background']['color']);
345
-        else
346
-            $this->_pdf->setFillColor(255);
347
-    }
348
-
349
-     /**
350
-     * add a level in the CSS history
351
-     *
352
-     * @access public
353
-     */
354
-    public function save()
355
-    {
356
-        array_push($this->table, $this->value);
357
-    }
358
-
359
-     /**
360
-     * remove a level in the CSS history
361
-     *
362
-     * @access public
363
-     */
364
-    public function load()
365
-    {
366
-        if (count($this->table)) {
367
-            $this->value = array_pop($this->table);
368
-        }
369
-    }
370
-
371
-     /**
372
-     * restore the Y positiony (used after a span)
373
-     *
374
-     * @access public
375
-     */
376
-    public function restorePosition()
377
-    {
378
-        if ($this->value['y']==$this->_pdf->getY()) $this->_pdf->setY($this->value['yc'], false);
379
-    }
380
-
381
-     /**
382
-     * set the New position for the current Tag
383
-     *
384
-     * @access public
385
-     */
386
-    public function setPosition()
387
-    {
388
-        // get the current position
389
-        $currentX = $this->_pdf->getX();
390
-        $currentY = $this->_pdf->getY();
391
-
392
-        // save it
393
-        $this->value['xc'] = $currentX;
394
-        $this->value['yc'] = $currentY;
395
-
396
-        if ($this->value['position']=='relative' || $this->value['position']=='absolute') {
397
-            if ($this->value['right']!==null) {
398
-                $x = $this->getLastWidth(true) - $this->value['right'] - $this->value['width'];
399
-                if ($this->value['margin']['r']) $x-= $this->value['margin']['r'];
400
-            } else {
401
-                $x = $this->value['left'];
402
-                if ($this->value['margin']['l']) $x+= $this->value['margin']['l'];
403
-            }
404
-
405
-            if ($this->value['bottom']!==null) {
406
-                $y = $this->getLastHeight(true) - $this->value['bottom'] - $this->value['height'];
407
-                if ($this->value['margin']['b']) $y-= $this->value['margin']['b'];
408
-            } else {
409
-                $y = $this->value['top'];
410
-                if ($this->value['margin']['t']) $y+= $this->value['margin']['t'];
411
-            }
412
-
413
-            if ($this->value['position']=='relative') {
414
-                $this->value['x'] = $currentX + $x;
415
-                $this->value['y'] = $currentY + $y;
416
-            } else {
417
-                $this->value['x'] = $this->_getLastAbsoluteX()+$x;
418
-                $this->value['y'] = $this->_getLastAbsoluteY()+$y;
419
-            }
420
-        } else {
421
-            $this->value['x'] = $currentX;
422
-            $this->value['y'] = $currentY;
423
-            if ($this->value['margin']['l']) $this->value['x']+= $this->value['margin']['l'];
424
-            if ($this->value['margin']['t']) $this->value['y']+= $this->value['margin']['t'];
425
-        }
426
-
427
-        // save the new position
428
-        $this->_pdf->setXY($this->value['x'], $this->value['y']);
429
-    }
430
-
431
-     /**
432
-     * Analise the CSS style to convert it into Form style
433
-     *
434
-     * @access public
435
-     * @param  array    styles
436
-     */
437
-    public function getFormStyle()
438
-    {
439
-        $prop = array();
440
-
441
-        $prop['alignment'] = $this->value['text-align'];
442
-
443
-        if (isset($this->value['background']['color']) && is_array($this->value['background']['color'])) {
444
-            $prop['fillColor'] = $this->value['background']['color'];
445
-        }
446
-
447
-        if (isset($this->value['border']['t']['color'])) {
448
-            $prop['strokeColor'] = $this->value['border']['t']['color'];
449
-        }
450
-
451
-        if (isset($this->value['border']['t']['width'])) {
452
-            $prop['lineWidth'] = $this->value['border']['t']['width'];
453
-        }
454
-
455
-        if (isset($this->value['border']['t']['type'])) {
456
-            $prop['borderStyle'] = $this->value['border']['t']['type'];
457
-        }
458
-
459
-        if (!empty($this->value['color'])) {
460
-            $prop['textColor'] = $this->value['color'];
461
-        }
462
-
463
-        if (!empty($this->value['font-size'])) {
464
-            $prop['textSize'] = $this->value['font-size'];
465
-        }
466
-
467
-        return $prop;
468
-    }
469
-
470
-     /**
471
-     * Analise the CSS style to convert it into SVG style
472
-     *
473
-     * @access public
474
-     * @param  string   tag name
475
-     * @param  array    styles
476
-     */
477
-    public function getSvgStyle($tagName, &$param)
478
-    {
479
-        // prepare
480
-        $tagName = strtolower($tagName);
481
-        $id   = isset($param['id'])   ? strtolower(trim($param['id']))   : null; if (!$id)   $id   = null;
482
-        $name = isset($param['name']) ? strtolower(trim($param['name'])) : null; if (!$name) $name = null;
483
-
484
-        // read the class attribute
485
-        $class = array();
486
-        $tmp = isset($param['class']) ? strtolower(trim($param['class'])) : '';
487
-        $tmp = explode(' ', $tmp);
488
-        foreach ($tmp as $k => $v) {
489
-            $v = trim($v);
490
-            if ($v) $class[] = $v;
491
-        }
492
-
493
-        // identify the tag, and the direct styles
494
-        $this->value['id_tag'] = $tagName;
495
-        $this->value['id_name']   = $name;
496
-        $this->value['id_id']     = $id;
497
-        $this->value['id_class']  = $class;
498
-        $this->value['id_lst']    = array();
499
-        $this->value['id_lst'][] = '*';
500
-        $this->value['id_lst'][] = $tagName;
501
-        if (!isset($this->value['svg'])) {
502
-            $this->value['svg'] = array(
503
-                'stroke'         => null,
504
-                'stroke-width'   => $this->convertToMM('1pt'),
505
-                'fill'           => null,
506
-                'fill-opacity'   => null,
507
-            );
508
-        }
509
-
510
-        if (count($class)) {
511
-            foreach ($class as $v) {
512
-                $this->value['id_lst'][] = '*.'.$v;
513
-                $this->value['id_lst'][] = '.'.$v;
514
-                $this->value['id_lst'][] = $tagName.'.'.$v;
515
-            }
516
-        }
517
-        if ($id) {
518
-            $this->value['id_lst'][] = '*#'.$id;
519
-            $this->value['id_lst'][] = '#'.$id;
520
-            $this->value['id_lst'][] = $tagName.'#'.$id;
521
-        }
522
-
523
-        // CSS style
524
-        $styles = $this->_getFromCSS();
525
-
526
-        // adding the style from the tag
527
-        $styles = array_merge($styles, $param['style']);
528
-
529
-        if (isset($styles['stroke']))        $this->value['svg']['stroke']       = $this->convertToColor($styles['stroke'], $res);
530
-        if (isset($styles['stroke-width']))  $this->value['svg']['stroke-width'] = $this->convertToMM($styles['stroke-width']);
531
-        if (isset($styles['fill']))          $this->value['svg']['fill']         = $this->convertToColor($styles['fill'], $res);
532
-        if (isset($styles['fill-opacity']))  $this->value['svg']['fill-opacity'] = 1.*$styles['fill-opacity'];
533
-
534
-        return $this->value['svg'];
535
-    }
536
-
537
-    /**
538
-     * analyse the css properties from the HTML parsing
539
-     *
540
-     * @access public
541
-     * @param  string  $tagName
542
-     * @param  array   $param
543
-     * @param  array   $legacy
544
-     */
545
-    public function analyse($tagName, &$param, $legacy = null)
546
-    {
547
-        // prepare the informations
548
-        $tagName = strtolower($tagName);
549
-        $id   = isset($param['id'])   ? strtolower(trim($param['id']))    : null; if (!$id)   $id   = null;
550
-        $name = isset($param['name']) ? strtolower(trim($param['name']))  : null; if (!$name) $name = null;
551
-
552
-        // get the class names to use
553
-        $class = array();
554
-        $tmp = isset($param['class']) ? strtolower(trim($param['class'])) : '';
555
-        $tmp = explode(' ', $tmp);
556
-        foreach ($tmp as $k => $v) {
557
-            $v = trim($v);
558
-            if ($v) $class[] = $v;
559
-        }
560
-
561
-        // prepare the values, and the list of css tags to identify
562
-        $this->value['id_tag']   = $tagName;
563
-        $this->value['id_name']  = $name;
564
-        $this->value['id_id']    = $id;
565
-        $this->value['id_class'] = $class;
566
-        $this->value['id_lst']   = array();
567
-        $this->value['id_lst'][] = '*';
568
-        $this->value['id_lst'][] = $tagName;
569
-        if (count($class)) {
570
-            foreach ($class as $v) {
571
-                $this->value['id_lst'][] = '*.'.$v;
572
-                $this->value['id_lst'][] = '.'.$v;
573
-                $this->value['id_lst'][] = $tagName.'.'.$v;
574
-            }
575
-        }
576
-        if ($id) {
577
-            $this->value['id_lst'][] = '*#'.$id;
578
-            $this->value['id_lst'][] = '#'.$id;
579
-            $this->value['id_lst'][] = $tagName.'#'.$id;
580
-        }
581
-
582
-        // get the css styles from class
583
-        $styles = $this->_getFromCSS();
584
-
585
-        // merge with the css styles from tag
586
-        $styles = array_merge($styles, $param['style']);
587
-        if (isset($param['allwidth']) && !isset($styles['width'])) $styles['width'] = '100%';
588
-
589
-        // reset some styles, depending on the tag name
590
-        $this->resetStyle($tagName);
591
-
592
-        // add the legacy values
593
-        if ($legacy) {
594
-            foreach ($legacy as $legacyName => $legacyValue) {
595
-                if (is_array($legacyValue)) {
596
-                    foreach($legacyValue as $legacy2Name => $legacy2Value)
597
-                        $this->value[$legacyName][$legacy2Name] = $legacy2Value;
598
-                } else {
599
-                    $this->value[$legacyName] = $legacyValue;
600
-                }
601
-            }
602
-        }
603
-
604
-        // some flags
605
-        $correctWidth = false;
606
-        $noWidth = true;
607
-
608
-        // read all the css styles
609
-        foreach ($styles as $nom => $val) {
610
-            switch($nom)
611
-            {
612
-                case 'font-family':
613
-                    $val = explode(',', $val);
614
-                    $val = trim($val[0]);
615
-                    if ($val) $this->value['font-family'] = $val;
616
-                    break;
617
-
618
-                case 'font-weight':
619
-                    $this->value['font-bold'] = ($val=='bold');
620
-                    break;
621
-
622
-                case 'font-style':
623
-                    $this->value['font-italic'] = ($val=='italic');
624
-                    break;
625
-
626
-                case 'text-decoration':
627
-                    $val = explode(' ', $val);
628
-                    $this->value['font-underline']   = (in_array('underline', $val));
629
-                    $this->value['font-overline']    = (in_array('overline', $val));
630
-                    $this->value['font-linethrough'] = (in_array('line-through', $val));
631
-                    break;
632
-
633
-                case 'text-indent':
634
-                    $this->value['text-indent'] = $this->convertToMM($val);
635
-                    break;
636
-
637
-                case 'text-transform':
638
-                    if (!in_array($val, array('none', 'capitalize', 'uppercase', 'lowercase'))) $val = 'none';
639
-                    $this->value['text-transform']  = $val;
640
-                    break;
641
-
642
-                case 'font-size':
643
-                    $val = $this->convertToMM($val, $this->value['font-size']);
644
-                    if ($val) $this->value['font-size'] = $val;
645
-                    break;
646
-
647
-                case 'color':
648
-                    $res = null;
649
-                    $this->value['color'] = $this->convertToColor($val, $res);
650
-                    if ($tagName=='hr') {
651
-                        $this->value['border']['l']['color'] = $this->value['color'];
652
-                        $this->value['border']['t']['color'] = $this->value['color'];
653
-                        $this->value['border']['r']['color'] = $this->value['color'];
654
-                        $this->value['border']['b']['color'] = $this->value['color'];
655
-                    }
656
-                    break;
657
-
658
-                case 'text-align':
659
-                    $val = strtolower($val);
660
-                    if (!in_array($val, array('left', 'right', 'center', 'justify', 'li_right'))) $val = 'left';
661
-                    $this->value['text-align'] = $val;
662
-                    break;
663
-
664
-                case 'vertical-align':
665
-                    $this->value['vertical-align'] = $val;
666
-                    break;
667
-
668
-                case 'width':
669
-                    $this->value['width'] = $this->convertToMM($val, $this->getLastWidth());
670
-                    if ($this->value['width'] && substr($val, -1)=='%') $correctWidth=true;
671
-                    $noWidth = false;
672
-                    break;
673
-
674
-                case 'height':
675
-                    $this->value['height'] = $this->convertToMM($val, $this->getLastHeight());
676
-                    break;
677
-
678
-                case 'line-height':
679
-                    if (preg_match('/^[0-9\.]+$/isU', $val)) $val = floor($val*100).'%';
680
-                    $this->value['line-height'] = $val;
681
-                    break;
682
-
683
-                case 'rotate':
684
-                    if (!in_array($val, array(0, -90, 90, 180, 270, -180, -270))) $val = null;
685
-                    if ($val<0) $val+= 360;
686
-                    $this->value['rotate'] = $val;
687
-                    break;
688
-
689
-                case 'overflow':
690
-                    if (!in_array($val, array('visible', 'hidden'))) $val = 'visible';
691
-                    $this->value['overflow'] = $val;
692
-                    break;
693
-
694
-                case 'padding':
695
-                    $val = explode(' ', $val);
696
-                    foreach ($val as $k => $v) {
697
-                        $v = trim($v);
698
-                        if ($v!='') {
699
-                            $val[$k] = $v;
700
-                        } else {
701
-                            unset($val[$k]);
702
-                        }
703
-                    }
704
-                    $val = array_values($val);
705
-                    $this->_duplicateBorder($val);
706
-                    $this->value['padding']['t'] = $this->convertToMM($val[0], 0);
707
-                    $this->value['padding']['r'] = $this->convertToMM($val[1], 0);
708
-                    $this->value['padding']['b'] = $this->convertToMM($val[2], 0);
709
-                    $this->value['padding']['l'] = $this->convertToMM($val[3], 0);
710
-                    break;
711
-
712
-                case 'padding-top':
713
-                    $this->value['padding']['t'] = $this->convertToMM($val, 0);
714
-                    break;
715
-
716
-                case 'padding-right':
717
-                    $this->value['padding']['r'] = $this->convertToMM($val, 0);
718
-                    break;
719
-
720
-                case 'padding-bottom':
721
-                    $this->value['padding']['b'] = $this->convertToMM($val, 0);
722
-                    break;
723
-
724
-                case 'padding-left':
725
-                    $this->value['padding']['l'] = $this->convertToMM($val, 0);
726
-                    break;
727
-
728
-                case 'margin':
729
-                    if ($val=='auto') {
730
-                        $this->value['margin-auto'] = true;
731
-                        break;
732
-                    }
733
-                    $val = explode(' ', $val);
734
-                    foreach ($val as $k => $v) {
735
-                        $v = trim($v);
736
-                        if ($v!='') {
737
-                            $val[$k] = $v;
738
-                        } else {
739
-                            unset($val[$k]);
740
-                        }
741
-                    }
742
-                    $val = array_values($val);
743
-                    $this->_duplicateBorder($val);
744
-                    $this->value['margin']['t'] = $this->convertToMM($val[0], 0);
745
-                    $this->value['margin']['r'] = $this->convertToMM($val[1], 0);
746
-                    $this->value['margin']['b'] = $this->convertToMM($val[2], 0);
747
-                    $this->value['margin']['l'] = $this->convertToMM($val[3], 0);
748
-                    break;
749
-
750
-                case 'margin-top':
751
-                    $this->value['margin']['t'] = $this->convertToMM($val, 0);
752
-                    break;
753
-
754
-                case 'margin-right':
755
-                    $this->value['margin']['r'] = $this->convertToMM($val, 0);
756
-                    break;
757
-
758
-                case 'margin-bottom':
759
-                    $this->value['margin']['b'] = $this->convertToMM($val, 0);
760
-                    break;
761
-
762
-                case 'margin-left':
763
-                    $this->value['margin']['l'] = $this->convertToMM($val, 0);
764
-                    break;
765
-
766
-                case 'border':
767
-                    $val = $this->readBorder($val);
768
-                    $this->value['border']['t'] = $val;
769
-                    $this->value['border']['r'] = $val;
770
-                    $this->value['border']['b'] = $val;
771
-                    $this->value['border']['l'] = $val;
772
-                    break;
773
-
774
-                case 'border-style':
775
-                    $val = explode(' ', $val);
776
-                    foreach ($val as $valK => $valV) {
777
-                        if (!in_array($valV, array('solid', 'dotted', 'dashed'))) {
778
-                            $val[$valK] = null;
779
-                        }
780
-                    }
781
-                    $this->_duplicateBorder($val);
782
-                    if ($val[0]) $this->value['border']['t']['type'] = $val[0];
783
-                    if ($val[1]) $this->value['border']['r']['type'] = $val[1];
784
-                    if ($val[2]) $this->value['border']['b']['type'] = $val[2];
785
-                    if ($val[3]) $this->value['border']['l']['type'] = $val[3];
786
-                    break;
787
-
788
-                case 'border-top-style':
789
-                    if (in_array($val, array('solid', 'dotted', 'dashed'))) {
790
-                        $this->value['border']['t']['type'] = $val;
791
-                    }
792
-                    break;
793
-
794
-                case 'border-right-style':
795
-                    if (in_array($val, array('solid', 'dotted', 'dashed'))) {
796
-                        $this->value['border']['r']['type'] = $val;
797
-                    }
798
-                    break;
799
-
800
-                case 'border-bottom-style':
801
-                    if (in_array($val, array('solid', 'dotted', 'dashed'))) {
802
-                        $this->value['border']['b']['type'] = $val;
803
-                    }
804
-                    break;
805
-
806
-                case 'border-left-style':
807
-                    if (in_array($val, array('solid', 'dotted', 'dashed')))
808
-                        $this->value['border']['l']['type'] = $val;
809
-                    break;
810
-
811
-                case 'border-color':
812
-                    $res = false;
813
-                    $val = preg_replace('/,[\s]+/', ',', $val);
814
-                    $val = explode(' ', $val);
815
-                    foreach ($val as $valK => $valV) {
816
-                            $val[$valK] = $this->convertToColor($valV, $res);
817
-                            if (!$res) {
818
-                                $val[$valK] = null;
819
-                            }
820
-                    }
821
-                    $this->_duplicateBorder($val);
822
-                    if (is_array($val[0])) $this->value['border']['t']['color'] = $val[0];
823
-                    if (is_array($val[1])) $this->value['border']['r']['color'] = $val[1];
824
-                    if (is_array($val[2])) $this->value['border']['b']['color'] = $val[2];
825
-                    if (is_array($val[3])) $this->value['border']['l']['color'] = $val[3];
826
-
827
-                    break;
828
-
829
-                case 'border-top-color':
830
-                    $res = false;
831
-                    $val = $this->convertToColor($val, $res);
832
-                    if ($res) $this->value['border']['t']['color'] = $val;
833
-                    break;
834
-
835
-                case 'border-right-color':
836
-                    $res = false;
837
-                    $val = $this->convertToColor($val, $res);
838
-                    if ($res) $this->value['border']['r']['color'] = $val;
839
-                    break;
840
-
841
-                case 'border-bottom-color':
842
-                    $res = false;
843
-                    $val = $this->convertToColor($val, $res);
844
-                    if ($res) $this->value['border']['b']['color'] = $val;
845
-                    break;
846
-
847
-                case 'border-left-color':
848
-                    $res = false;
849
-                    $val = $this->convertToColor($val, $res);
850
-                    if ($res) $this->value['border']['l']['color'] = $val;
851
-                    break;
852
-
853
-                case 'border-width':
854
-                    $val = explode(' ', $val);
855
-                    foreach ($val as $valK => $valV) {
856
-                            $val[$valK] = $this->convertToMM($valV, 0);
857
-                    }
858
-                    $this->_duplicateBorder($val);
859
-                    if ($val[0]) $this->value['border']['t']['width'] = $val[0];
860
-                    if ($val[1]) $this->value['border']['r']['width'] = $val[1];
861
-                    if ($val[2]) $this->value['border']['b']['width'] = $val[2];
862
-                    if ($val[3]) $this->value['border']['l']['width'] = $val[3];
863
-                    break;
864
-
865
-                case 'border-top-width':
866
-                    $val = $this->convertToMM($val, 0);
867
-                    if ($val) $this->value['border']['t']['width'] = $val;
868
-                    break;
869
-
870
-                case 'border-right-width':
871
-                    $val = $this->convertToMM($val, 0);
872
-                    if ($val) $this->value['border']['r']['width'] = $val;
873
-                    break;
874
-
875
-                case 'border-bottom-width':
876
-                    $val = $this->convertToMM($val, 0);
877
-                    if ($val) $this->value['border']['b']['width'] = $val;
878
-                    break;
879
-
880
-                case 'border-left-width':
881
-                    $val = $this->convertToMM($val, 0);
882
-                    if ($val) $this->value['border']['l']['width'] = $val;
883
-                    break;
884
-
885
-                case 'border-collapse':
886
-                    if ($tagName=='table') $this->value['border']['collapse'] = ($val=='collapse');
887
-                    break;
888
-
889
-                case 'border-radius':
890
-                    $val = explode('/', $val);
891
-                    if (count($val)>2) {
892
-                        break;
893
-                    }
894
-                    $valH = $this->convertToRadius(trim($val[0]));
895
-                    if (count($valH)<1 || count($valH)>4) {
896
-                        break;
897
-                    }
898
-                    if (!isset($valH[1])) $valH[1] = $valH[0];
899
-                    if (!isset($valH[2])) $valH = array($valH[0], $valH[0], $valH[1], $valH[1]);
900
-                    if (!isset($valH[3])) $valH[3] = $valH[1];
901
-                    if (isset($val[1])) {
902
-                        $valV = $this->convertToRadius(trim($val[1]));
903
-                        if (count($valV)<1 || count($valV)>4) {
904
-                            break;
905
-                        }
906
-                        if (!isset($valV[1])) $valV[1] = $valV[0];
907
-                        if (!isset($valV[2])) $valV = array($valV[0], $valV[0], $valV[1], $valV[1]);
908
-                        if (!isset($valV[3])) $valV[3] = $valV[1];
909
-                    } else {
910
-                        $valV = $valH;
911
-                    }
912
-                    $this->value['border']['radius'] = array(
913
-                                'tl' => array($valH[0], $valV[0]),
914
-                                'tr' => array($valH[1], $valV[1]),
915
-                                'br' => array($valH[2], $valV[2]),
916
-                                'bl' => array($valH[3], $valV[3])
917
-                            );
918
-                    break;
919
-
920
-                case 'border-top-left-radius':
921
-                    $val = $this->convertToRadius($val);
922
-                    if (count($val)<1 || count($val)>2) {
923
-                        break;
924
-                    }
925
-                    $this->value['border']['radius']['tl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
926
-                    break;
927
-
928
-                case 'border-top-right-radius':
929
-                    $val = $this->convertToRadius($val);
930
-                    if (count($val)<1 || count($val)>2) {
931
-                        break;
932
-                    }
933
-                    $this->value['border']['radius']['tr'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
934
-                    break;
935
-
936
-                case 'border-bottom-right-radius':
937
-                    $val = $this->convertToRadius($val);
938
-                    if (count($val)<1 || count($val)>2) {
939
-                        break;
940
-                    }
941
-                    $this->value['border']['radius']['br'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
942
-                    break;
943
-
944
-                case 'border-bottom-left-radius':
945
-                    $val = $this->convertToRadius($val);
946
-                    if (count($val)<1 || count($val)>2) {
947
-                        break;
948
-                    }
949
-                    $this->value['border']['radius']['bl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
950
-                    break;
951
-
952
-                case 'border-top':
953
-                    $this->value['border']['t'] = $this->readBorder($val);
954
-                    break;
955
-
956
-                case 'border-right':
957
-                    $this->value['border']['r'] = $this->readBorder($val);
958
-                    break;
959
-
960
-                case 'border-bottom':
961
-                    $this->value['border']['b'] = $this->readBorder($val);
962
-                    break;
963
-
964
-                case 'border-left':
965
-                    $this->value['border']['l'] = $this->readBorder($val);
966
-                    break;
967
-
968
-                case 'background-color':
969
-                    $this->value['background']['color'] = $this->convertBackgroundColor($val);
970
-                    break;
971
-
972
-                case 'background-image':
973
-                    $this->value['background']['image'] = $this->convertBackgroundImage($val);
974
-                    break;
975
-
976
-                case 'background-position':
977
-                    $res = null;
978
-                    $this->value['background']['position'] = $this->convertBackgroundPosition($val, $res);
979
-                    break;
980
-
981
-                case 'background-repeat':
982
-                    $this->value['background']['repeat'] = $this->convertBackgroundRepeat($val);
983
-                    break;
984
-
985
-                case 'background':
986
-                    $this->convertBackground($val, $this->value['background']);
987
-                    break;
988
-
989
-                case 'position':
990
-                    if ($val=='absolute')       $this->value['position'] = 'absolute';
991
-                    else if ($val=='relative')  $this->value['position'] = 'relative';
992
-                    else                        $this->value['position'] = null;
993
-                    break;
994
-
995
-                case 'float':
996
-                    if ($val=='left')           $this->value['float'] = 'left';
997
-                    else if ($val=='right')     $this->value['float'] = 'right';
998
-                    else                        $this->value['float'] = null;
999
-                    break;
1000
-
1001
-                case 'display':
1002
-                    if ($val=='inline')         $this->value['display'] = 'inline';
1003
-                    else if ($val=='block')     $this->value['display'] = 'block';
1004
-                    else if ($val=='none')      $this->value['display'] = 'none';
1005
-                    else                        $this->value['display'] = null;
1006
-                    break;
1007
-
1008
-                case 'top':
1009
-                case 'bottom':
1010
-                case 'left':
1011
-                case 'right':
1012
-                    $this->value[$nom] = $val;
1013
-                    break;
1014
-
1015
-                case 'list-style':
1016
-                case 'list-style-type':
1017
-                case 'list-style-image':
1018
-                    if ($nom=='list-style') $nom = 'list-style-type';
1019
-                    $this->value[$nom] = $val;
1020
-                    break;
1021
-
1022
-                default:
1023
-                    break;
1024
-            }
1025
-        }
1026
-
1027
-        $return = true;
1028
-
1029
-        // only for P tag
1030
-        if ($this->value['margin']['t']===null) $this->value['margin']['t'] = $this->value['font-size'];
1031
-        if ($this->value['margin']['b']===null) $this->value['margin']['b'] = $this->value['font-size'];
1032
-
1033
-        // force the text align to left, if asked by html2pdf
1034
-        if ($this->_onlyLeft) $this->value['text-align'] = 'left';
1035
-
1036
-        // correction on the width (quick box)
1037
-        if ($noWidth && in_array($tagName, array('div', 'blockquote', 'fieldset')) && $this->value['position']!='absolute') {
1038
-            $this->value['width'] = $this->getLastWidth();
1039
-            $this->value['width']-= $this->value['margin']['l'] + $this->value['margin']['r'];
1040
-        } else {
1041
-            if ($correctWidth) {
1042
-                if (!in_array($tagName, array('table', 'div', 'blockquote', 'fieldset', 'hr'))) {
1043
-                    $this->value['width']-= $this->value['padding']['l'] + $this->value['padding']['r'];
1044
-                    $this->value['width']-= $this->value['border']['l']['width'] + $this->value['border']['r']['width'];
1045
-                }
1046
-                if (in_array($tagName, array('th', 'td'))) {
1047
-                    $this->value['width']-= $this->convertToMM(isset($param['cellspacing']) ? $param['cellspacing'] : '2px');
1048
-                    $return = false;
1049
-                }
1050
-                if ($this->value['width']<0) $this->value['width']=0;
1051
-            } else {
1052
-                if ($this->value['width']) {
1053
-                    if ($this->value['border']['l']['width']) $this->value['width'] += $this->value['border']['l']['width'];
1054
-                    if ($this->value['border']['r']['width']) $this->value['width'] += $this->value['border']['r']['width'];
1055
-                    if ($this->value['padding']['l'])         $this->value['width'] += $this->value['padding']['l'];
1056
-                    if ($this->value['padding']['r'])         $this->value['width'] += $this->value['padding']['r'];
1057
-                }
1058
-            }
1059
-        }
1060
-        if ($this->value['height']) {
1061
-            if ($this->value['border']['b']['width']) $this->value['height'] += $this->value['border']['b']['width'];
1062
-            if ($this->value['border']['t']['width']) $this->value['height'] += $this->value['border']['t']['width'];
1063
-            if ($this->value['padding']['b'])         $this->value['height'] += $this->value['padding']['b'];
1064
-            if ($this->value['padding']['t'])         $this->value['height'] += $this->value['padding']['t'];
1065
-        }
1066
-
1067
-        if ($this->value['top']!=null)      $this->value['top']     = $this->convertToMM($this->value['top'], $this->getLastHeight(true));
1068
-        if ($this->value['bottom']!=null)   $this->value['bottom']  = $this->convertToMM($this->value['bottom'], $this->getLastHeight(true));
1069
-        if ($this->value['left']!=null)     $this->value['left']    = $this->convertToMM($this->value['left'], $this->getLastWidth(true));
1070
-        if ($this->value['right']!=null)    $this->value['right']   = $this->convertToMM($this->value['right'], $this->getLastWidth(true));
1071
-
1072
-        if ($this->value['top'] && $this->value['bottom'] && $this->value['height'])    $this->value['bottom']  = null;
1073
-        if ($this->value['left'] && $this->value['right'] && $this->value['width'])     $this->value['right']   = null;
1074
-
1075
-        return $return;
1076
-    }
1077
-
1078
-     /**
1079
-     * get the height of the current line
1080
-     *
1081
-     * @access public
1082
-     * @return float $height in mm
1083
-     */
1084
-    public function getLineHeight()
1085
-    {
1086
-        $val = $this->value['line-height'];
1087
-        if ($val=='normal') $val = '108%';
1088
-        return $this->convertToMM($val, $this->value['font-size']);
1089
-    }
1090
-
1091
-     /**
1092
-     * get the width of the parent
1093
-     *
1094
-     * @access public
1095
-     * @param  boolean $mode true => adding padding and border
1096
-     * @return float $width in mm
1097
-     */
1098
-    public function getLastWidth($mode = false)
1099
-    {
1100
-        for ($k=count($this->table)-1; $k>=0; $k--) {
1101
-            if ($this->table[$k]['width']) {
1102
-                $w = $this->table[$k]['width'];
1103
-                if ($mode) {
1104
-                    $w+= $this->table[$k]['border']['l']['width'] + $this->table[$k]['padding']['l'] + 0.02;
1105
-                    $w+= $this->table[$k]['border']['r']['width'] + $this->table[$k]['padding']['r'] + 0.02;
1106
-                }
1107
-                return $w;
1108
-            }
1109
-        }
1110
-        return $this->_pdf->getW() - $this->_pdf->getlMargin() - $this->_pdf->getrMargin();
1111
-    }
1112
-
1113
-     /**
1114
-     * get the height of the parent
1115
-     *
1116
-     * @access public
1117
-     * @param  boolean $mode true => adding padding and border
1118
-     * @return float $height in mm
1119
-     */
1120
-    public function getLastHeight($mode = false)
1121
-    {
1122
-        for ($k=count($this->table)-1; $k>=0; $k--) {
1123
-            if ($this->table[$k]['height']) {
1124
-                $h = $this->table[$k]['height'];
1125
-                if ($mode) {
1126
-                    $h+= $this->table[$k]['border']['t']['width'] + $this->table[$k]['padding']['t'] + 0.02;
1127
-                    $h+= $this->table[$k]['border']['b']['width'] + $this->table[$k]['padding']['b'] + 0.02;
1128
-                }
1129
-                return $h;
1130
-            }
1131
-        }
1132
-        return $this->_pdf->getH() - $this->_pdf->gettMargin() - $this->_pdf->getbMargin();
1133
-    }
1134
-
1135
-    /**
1136
-     * get the value of the float property
1137
-     *
1138
-     * @access public
1139
-     * @return $float left/right
1140
-     */
1141
-    public function getFloat()
1142
-    {
1143
-        if ($this->value['float']=='left')    return 'left';
1144
-        if ($this->value['float']=='right')   return 'right';
1145
-        return null;
1146
-    }
1147
-
1148
-    /**
1149
-     * get the last value for a specific key
1150
-     *
1151
-     * @access public
1152
-     * @param  string $key
1153
-     * @return mixed
1154
-     */
1155
-    public function getLastValue($key)
1156
-    {
1157
-        $nb = count($this->table);
1158
-        if ($nb>0) {
1159
-            return $this->table[$nb-1][$key];
1160
-        } else {
1161
-            return null;
1162
-        }
1163
-    }
1164
-
1165
-    /**
1166
-     * get the last absolute X
1167
-     *
1168
-     * @access protected
1169
-     * @return float $x
1170
-     */
1171
-    protected function _getLastAbsoluteX()
1172
-    {
1173
-        for ($k=count($this->table)-1; $k>=0; $k--) {
1174
-            if ($this->table[$k]['x'] && $this->table[$k]['position']) return $this->table[$k]['x'];
1175
-        }
1176
-        return $this->_pdf->getlMargin();
1177
-    }
1178
-
1179
-    /**
1180
-     * get the last absolute Y
1181
-     *
1182
-     * @access protected
1183
-     * @return float $y
1184
-     */
1185
-    protected function _getLastAbsoluteY()
1186
-    {
1187
-        for ($k=count($this->table)-1; $k>=0; $k--) {
1188
-            if ($this->table[$k]['y'] && $this->table[$k]['position']) return $this->table[$k]['y'];
1189
-        }
1190
-        return $this->_pdf->gettMargin();
1191
-    }
1192
-
1193
-    /**
1194
-     * get the CSS properties of the current tag
1195
-     *
1196
-     * @access protected
1197
-     * @return array $styles
1198
-     */
1199
-    protected function _getFromCSS()
1200
-    {
1201
-        // styles to apply
1202
-        $styles = array();
1203
-
1204
-        // list of the selectors to get in the CSS files
1205
-        $getit  = array();
1206
-
1207
-        // get the list of the selectors of each tags
1208
-        $lst = array();
1209
-        $lst[] = $this->value['id_lst'];
1210
-        for ($i=count($this->table)-1; $i>=0; $i--) {
1211
-            $lst[] = $this->table[$i]['id_lst'];
1212
-        }
1213
-
1214
-        // foreach selectors in the CSS files, verify if it match with the list of selectors
1215
-        foreach ($this->cssKeys as $key => $num) {
1216
-            if ($this->_getReccursiveStyle($key, $lst)) {
1217
-                $getit[$key] = $num;
1218
-            }
1219
-        }
1220
-
1221
-        // if we have selectors
1222
-        if (count($getit)) {
1223
-            // get them, but in the definition order, because of priority
1224
-            asort($getit);
1225
-            foreach ($getit as $key => $val) $styles = array_merge($styles, $this->css[$key]);
1226
-        }
1227
-
1228
-        return $styles;
1229
-    }
1230
-
1231
-    /**
1232
-     * identify if the selector $key match with the list of tag selectors
1233
-     *
1234
-     * @access protected
1235
-     * @param  string   $key CSS selector to analyse
1236
-     * @param  array    $lst list of the selectors of each tags
1237
-     * @param  string   $next next step of parsing the selector
1238
-     * @return boolean
1239
-     */
1240
-    protected function _getReccursiveStyle($key, $lst, $next = null)
1241
-    {
1242
-        // if next step
1243
-        if ($next!==null) {
1244
-            // we remove this step
1245
-            if ($next) $key = trim(substr($key, 0, -strlen($next)));
1246
-            array_shift($lst);
1247
-
1248
-            // if no more step to identify => return false
1249
-            if (!count($lst)) {
1250
-                return false;
1251
-            }
1252
-        }
1253
-
1254
-        // for each selector of the current step
1255
-        foreach ($lst[0] as $name) {
1256
-            // if selector = key => ok
1257
-            if ($key==$name) {
1258
-                return true;
1259
-            }
1260
-
1261
-            // if the end of the key = the selector and the next step is ok => ok
1262
-            if (substr($key, -strlen(' '.$name))==' '.$name && $this->_getReccursiveStyle($key, $lst, $name)) {
1263
-                return true;
1264
-            }
1265
-        }
1266
-
1267
-        // if we are not in the first step, we analyse the sub steps (the pareng tag of the current tag)
1268
-        if ($next!==null && $this->_getReccursiveStyle($key, $lst, '')) {
1269
-            return true;
1270
-        }
1271
-
1272
-        // no corresponding found
1273
-        return false;
1274
-    }
1275
-
1276
-    /**
1277
-     * Analyse a border
1278
-     *
1279
-     * @access  public
1280
-     * @param   string $css css border properties
1281
-     * @return  array  border properties
1282
-     */
1283
-    public function readBorder($css)
1284
-    {
1285
-        // border none
1286
-        $none = array('type' => 'none', 'width' => 0, 'color' => array(0, 0, 0));
1287
-
1288
-        // default value
1289
-        $type  = 'solid';
1290
-        $width = $this->convertToMM('1pt');
1291
-        $color = array(0, 0, 0);
1292
-
1293
-        // clean up the values
1294
-        $css = explode(' ', $css);
1295
-        foreach ($css as $k => $v) {
1296
-            $v = trim($v);
1297
-            if ($v) $css[$k] = $v;
1298
-            else    unset($css[$k]);
1299
-        }
1300
-        $css = array_values($css);
1301
-
1302
-        // read the values
1303
-        $res = null;
1304
-        foreach ($css as $value) {
1305
-
1306
-            // if no border => return none
1307
-            if ($value=='none' || $value=='hidden') {
1308
-                return $none;
1309
-            }
1310
-
1311
-            // try to convert the value as a distance
1312
-            $tmp = $this->convertToMM($value);
1313
-
1314
-            // if the convert is ok => it is a width
1315
-            if ($tmp!==null) {
1316
-                $width = $tmp;
1317
-            // else, it could be the type
1318
-            } else if (in_array($value, array('solid', 'dotted', 'dashed', 'double'))) {
1319
-                $type = $value;
1320
-            // else, it could be the color
1321
-            } else {
1322
-                $tmp = $this->convertToColor($value, $res);
1323
-                if ($res) $color = $tmp;
1324
-            }
1325
-        }
1326
-
1327
-        // if no witdh => return none
1328
-        if (!$width) return $none;
1329
-
1330
-        // return the border properties
1331
-        return array('type' => $type, 'width' => $width, 'color' => $color);
1332
-    }
1333
-
1334
-    /**
1335
-     * duplicate the borders if needed
1336
-     *
1337
-     * @access protected
1338
-     * @param  &array $val
1339
-     */
1340
-    protected function _duplicateBorder(&$val)
1341
-    {
1342
-        // 1 value => L => RTB
1343
-        if (count($val)==1) {
1344
-            $val[1] = $val[0];
1345
-            $val[2] = $val[0];
1346
-            $val[3] = $val[0];
1347
-        // 2 values => L => R & T => B
1348
-        } else if (count($val)==2) {
1349
-            $val[2] = $val[0];
1350
-            $val[3] = $val[1];
1351
-        // 3 values => T => B
1352
-        } else if (count($val)==3) {
1353
-            $val[3] = $val[1];
1354
-        }
1355
-    }
1356
-
1357
-    /**
1358
-     * Analyse a background
1359
-     *
1360
-     * @access public
1361
-     * @param  string $css css background properties
1362
-     * @param  &array $value parsed values (by reference, because, ther is a legacy of the parent CSS properties)
1363
-     */
1364
-    public function convertBackground($css, &$value)
1365
-    {
1366
-        // is there a image ?
1367
-        $text = '/url\(([^)]*)\)/isU';
1368
-        if (preg_match($text, $css, $match)) {
1369
-            // get the image
1370
-            $value['image'] = $this->convertBackgroundImage($match[0]);
1371
-
1372
-            // remove if from the css properties
1373
-            $css = preg_replace($text, '', $css);
1374
-            $css = preg_replace('/[\s]+/', ' ', $css);
1375
-        }
1376
-
1377
-        // protect some spaces
1378
-        $css = preg_replace('/,[\s]+/', ',', $css);
1379
-
1380
-        // explode the values
1381
-        $css = explode(' ', $css);
1382
-
1383
-        // background position to parse
1384
-        $pos = '';
1385
-
1386
-        // foreach value
1387
-        foreach ($css as $val) {
1388
-            // try to parse the value as a color
1389
-            $ok = false;
1390
-            $color = $this->convertToColor($val, $ok);
1391
-
1392
-            // if ok => it is a color
1393
-            if ($ok) {
1394
-                $value['color'] = $color;
1395
-            // else if transparent => no coloàr
1396
-            } else if ($val=='transparent') {
1397
-                $value['color'] = null;
1398
-            // else
1399
-            } else {
1400
-                // try to parse the value as a repeat
1401
-                $repeat = $this->convertBackgroundRepeat($val);
1402
-
1403
-                // if ok => it is repeat
1404
-                if ($repeat) {
1405
-                    $value['repeat'] = $repeat;
1406
-                // else => it could only be a position
1407
-                } else {
1408
-                    $pos.= ($pos ? ' ' : '').$val;
1409
-                }
1410
-            }
1411
-        }
1412
-
1413
-        // if we have a position to parse
1414
-        if ($pos) {
1415
-            // try to read it
1416
-            $pos = $this->convertBackgroundPosition($pos, $ok);
1417
-            if ($ok) $value['position'] = $pos;
1418
-        }
1419
-    }
1420
-
1421
-    /**
1422
-     * parse a background color
1423
-     *
1424
-     * @access public
1425
-     * @param  string $css
1426
-     * @return string $value
1427
-     */
1428
-    public function convertBackgroundColor($css)
1429
-    {
1430
-        $res = null;
1431
-        if ($css=='transparent') return null;
1432
-        else                     return $this->convertToColor($css, $res);
1433
-    }
1434
-
1435
-    /**
1436
-     * parse a background image
1437
-     *
1438
-     * @access public
1439
-     * @param  string $css
1440
-     * @return string $value
1441
-     */
1442
-    public function convertBackgroundImage($css)
1443
-    {
1444
-        if ($css=='none')
1445
-            return null;
1446
-        else if (preg_match('/^url\(([^)]*)\)$/isU', $css, $match))
1447
-            return $match[1];
1448
-        else
1449
-            return null;
1450
-    }
1451
-
1452
-    /**
1453
-     * parse a background position
1454
-     *
1455
-     * @access public
1456
-     * @param  string $css
1457
-     * @param  &boolean $res flag if conver is ok or not
1458
-     * @return array ($x, $y)
1459
-     */
1460
-    public function convertBackgroundPosition($css, &$res)
1461
-    {
1462
-        // init the res
1463
-        $res = false;
1464
-
1465
-        // explode the value
1466
-        $css = explode(' ', $css);
1467
-
1468
-        // we must have 2 values. if 0 or >2 : error. if 1 => put center for 2
1469
-        if (count($css)<2) {
1470
-            if (!$css[0]) return null;
1471
-            $css[1] = 'center';
1472
-        }
1473
-        if (count($css)>2) return null;
1474
-
1475
-        // prepare the values
1476
-        $x = 0;
1477
-        $y = 0;
1478
-        $res = true;
1479
-
1480
-        // convert the first value
1481
-        if ($css[0]=='left')        $x = '0%';
1482
-        else if ($css[0]=='center') $x = '50%';
1483
-        else if ($css[0]=='right')  $x = '100%';
1484
-        else if ($css[0]=='top')    $y = '0%';
1485
-        else if ($css[0]=='bottom') $y = '100%';
1486
-        else if (preg_match('/^[-]?[0-9\.]+%$/isU', $css[0])) $x = $css[0];
1487
-        else if ($this->convertToMM($css[0])) $x = $this->convertToMM($css[0]);
1488
-        else $res = false;
1489
-
1490
-        // convert the second value
1491
-        if ($css[1]=='left')        $x = '0%';
1492
-        else if ($css[1]=='right')  $x = '100%';
1493
-        else if ($css[1]=='top')    $y = '0%';
1494
-        else if ($css[1]=='center') $y = '50%';
1495
-        else if ($css[1]=='bottom') $y = '100%';
1496
-        else if (preg_match('/^[-]?[0-9\.]+%$/isU', $css[1])) $y = $css[1];
1497
-        else if ($this->convertToMM($css[1])) $y = $this->convertToMM($css[1]);
1498
-        else $res = false;
1499
-
1500
-        // return the values
1501
-        return array($x, $y);
1502
-    }
1503
-
1504
-    /**
1505
-     * parse a background repeat
1506
-     *
1507
-     * @access public
1508
-     * @param  string $css
1509
-     * @return string $value
1510
-     */
1511
-    public function convertBackgroundRepeat($css)
1512
-    {
1513
-        switch($css)
1514
-        {
1515
-            case 'repeat':
1516
-                return array(true, true);
1517
-            case 'repeat-x':
1518
-                return array(true, false);
1519
-            case 'repeat-y':
1520
-                return array(false, true);
1521
-            case 'no-repeat':
1522
-                return array(false, false);
1523
-        }
1524
-        return null;
1525
-    }
1526
-
1527
-     /**
1528
-     * convert a distance to mm
1529
-     *
1530
-     * @access public
1531
-     * @param  string $css distance to convert
1532
-     * @param  float  $old parent distance
1533
-     * @return float  $value
1534
-     */
1535
-    public function convertToMM($css, $old=0.)
1536
-    {
1537
-        $css = trim($css);
1538
-        if (preg_match('/^[0-9\.\-]+$/isU', $css))        $css.= 'px';
1539
-        if (preg_match('/^[0-9\.\-]+px$/isU', $css))      $css = 25.4/96. * str_replace('px', '', $css);
1540
-        else if (preg_match('/^[0-9\.\-]+pt$/isU', $css)) $css = 25.4/72. * str_replace('pt', '', $css);
1541
-        else if (preg_match('/^[0-9\.\-]+in$/isU', $css)) $css = 25.4 * str_replace('in', '', $css);
1542
-        else if (preg_match('/^[0-9\.\-]+mm$/isU', $css)) $css = 1.*str_replace('mm', '', $css);
1543
-        else if (preg_match('/^[0-9\.\-]+%$/isU', $css))  $css = 1.*$old*str_replace('%', '', $css)/100.;
1544
-        else                                              $css = null;
1545
-
1546
-        return $css;
1547
-    }
1548
-
1549
-    /**
1550
-     * convert a css radius
1551
-     *
1552
-     * @access public
1553
-     * @param  string $css
1554
-     * @return float  $value
1555
-     */
1556
-    public function convertToRadius($css)
1557
-    {
1558
-        // explode the value
1559
-        $css = explode(' ', $css);
1560
-
1561
-        foreach ($css as $k => $v) {
1562
-            $v = trim($v);
1563
-            if ($v) {
1564
-                $v = $this->convertToMM($v, 0);
1565
-                if ($v!==null) {
1566
-                    $css[$k] = $v;
1567
-                } else {
1568
-                    unset($css[$k]);
1569
-                }
1570
-            } else {
1571
-                unset($css[$k]);
1572
-            }
1573
-        }
1574
-
1575
-        return array_values($css);
1576
-    }
1577
-
1578
-    /**
1579
-     * convert a css color
1580
-     *
1581
-     * @access public
1582
-     * @param  string $css
1583
-     * @param  &boolean $res
1584
-     * @return array (r,g, b)
1585
-     */
1586
-    public function convertToColor($css, &$res)
1587
-    {
1588
-        // prepare the value
1589
-        $css = trim($css);
1590
-        $res = true;
1591
-
1592
-        // if transparent => return null
1593
-        if (strtolower($css)=='transparent') return array(null, null, null);
1594
-
1595
-        // HTML color
1596
-        if (isset($this->_htmlColor[strtolower($css)])) {
1597
-            $css = $this->_htmlColor[strtolower($css)];
1598
-            $r = floatVal(hexdec(substr($css, 0, 2)));
1599
-            $v = floatVal(hexdec(substr($css, 2, 2)));
1600
-            $b = floatVal(hexdec(substr($css, 4, 2)));
1601
-            return array($r, $v, $b);
1602
-        }
1603
-
1604
-        // like #FFFFFF
1605
-        if (preg_match('/^#[0-9A-Fa-f]{6}$/isU', $css)) {
1606
-            $r = floatVal(hexdec(substr($css, 1, 2)));
1607
-            $v = floatVal(hexdec(substr($css, 3, 2)));
1608
-            $b = floatVal(hexdec(substr($css, 5, 2)));
1609
-            return array($r, $v, $b);
1610
-        }
1611
-
1612
-        // like #FFF
1613
-        if (preg_match('/^#[0-9A-F]{3}$/isU', $css)) {
1614
-            $r = floatVal(hexdec(substr($css, 1, 1).substr($css, 1, 1)));
1615
-            $v = floatVal(hexdec(substr($css, 2, 1).substr($css, 2, 1)));
1616
-            $b = floatVal(hexdec(substr($css, 3, 1).substr($css, 3, 1)));
1617
-            return array($r, $v, $b);
1618
-        }
1619
-
1620
-        // like rgb(100, 100, 100)
1621
-        if (preg_match('/rgb\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $css, $match)) {
1622
-            $r = $this->_convertSubColor($match[1]);
1623
-            $v = $this->_convertSubColor($match[2]);
1624
-            $b = $this->_convertSubColor($match[3]);
1625
-            return array($r*255., $v*255., $b*255.);
1626
-        }
1627
-
1628
-        // like cmyk(100, 100, 100, 100)
1629
-        if (preg_match('/cmyk\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $css, $match)) {
1630
-            $c = $this->_convertSubColor($match[1]);
1631
-            $m = $this->_convertSubColor($match[2]);
1632
-            $y = $this->_convertSubColor($match[3]);
1633
-            $k = $this->_convertSubColor($match[4]);
1634
-            return array($c*100., $m*100., $y*100., $k*100.);
1635
-        }
1636
-
1637
-        $res = false;
1638
-        return array(0., 0., 0.);
1639
-    }
1640
-
1641
-    /**
1642
-     * color value to convert
1643
-     *
1644
-     * @access protected
1645
-     * @param  string $c
1646
-     * @return float $c 0.->1.
1647
-     */
1648
-    protected function _convertSubColor($c)
1649
-    {
1650
-        if (substr($c, -1)=='%') {
1651
-            $c = floatVal(substr($c, 0, -1))/100.;
1652
-        } else {
1653
-            $c = floatVal($c);
1654
-            if ($c>1) $c = $c/255.;
1655
-        }
1656
-
1657
-        return $c;
1658
-    }
1659
-
1660
-    /**
1661
-     * read a css content
1662
-     *
1663
-     * @access protected
1664
-     * @param  &string $code
1665
-     */
1666
-    protected function _analyseStyle(&$code)
1667
-    {
1668
-        // clean the spaces
1669
-        $code = preg_replace('/[\s]+/', ' ', $code);
1670
-
1671
-        // remove the comments
1672
-        $code = preg_replace('/\/\*.*?\*\//s', '', $code);
1673
-
1674
-        // split each CSS code "selector { value }"
1675
-        preg_match_all('/([^{}]+){([^}]*)}/isU', $code, $match);
1676
-
1677
-        // for each CSS code
1678
-        for ($k=0; $k<count($match[0]); $k++) {
1679
-
1680
-            // selectors
1681
-            $names = strtolower(trim($match[1][$k]));
1682
-
1683
-            // css style
1684
-            $styles = trim($match[2][$k]);
1685
-
1686
-            // explode each value
1687
-            $styles = explode(';', $styles);
1688
-
1689
-            // parse each value
1690
-            $css = array();
1691
-            foreach ($styles as $style) {
1692
-                $tmp = explode(':', $style);
1693
-                if (count($tmp)>1) {
1694
-                    $cod = $tmp[0]; unset($tmp[0]); $tmp = implode(':', $tmp);
1695
-                    $css[trim(strtolower($cod))] = trim($tmp);
1696
-                }
1697
-            }
1698
-
1699
-            // explode the names
1700
-            $names = explode(',', $names);
1701
-
1702
-            // save the values for each names
1703
-            foreach ($names as $name) {
1704
-                // clean the name
1705
-                $name = trim($name);
1706
-
1707
-                // if a selector with somethink lige :hover => continue
1708
-                if (strpos($name, ':')!==false) continue;
1709
-
1710
-                // save the value
1711
-                if (!isset($this->css[$name]))
1712
-                    $this->css[$name] = $css;
1713
-                else
1714
-                    $this->css[$name] = array_merge($this->css[$name], $css);
1715
-
1716
-            }
1717
-        }
1718
-
1719
-        // get he list of the keys
1720
-        $this->cssKeys = array_flip(array_keys($this->css));
1721
-    }
1722
-
1723
-    /**
1724
-     * Extract the css files from a html code
1725
-     *
1726
-     * @access public
1727
-     * @param  string   &$html
1728
-     */
1729
-    public function readStyle(&$html)
1730
-    {
1731
-        // the CSS content
1732
-        $style = ' ';
1733
-
1734
-        // extract the link tags, and remove them in the html code
1735
-        preg_match_all('/<link([^>]*)>/isU', $html, $match);
1736
-        $html = preg_replace('/<link[^>]*>/isU', '', $html);
1737
-        $html = preg_replace('/<\/link[^>]*>/isU', '', $html);
1738
-
1739
-        // analyse each link tag
1740
-        foreach ($match[1] as $code) {
1741
-            $tmp = array();
1742
-
1743
-            // read the attributes name=value
1744
-            $prop = '([a-zA-Z0-9_]+)=([^"\'\s>]+)';
1745
-            preg_match_all('/'.$prop.'/is', $code, $match);
1746
-            for ($k=0; $k<count($match[0]); $k++) {
1747
-                $tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1748
-            }
1749
-
1750
-            // read the attributes name="value"
1751
-            $prop = '([a-zA-Z0-9_]+)=["]([^"]*)["]';
1752
-            preg_match_all('/'.$prop.'/is', $code, $match);
1753
-            for ($k=0; $k<count($match[0]); $k++) {
1754
-                $tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1755
-            }
1756
-
1757
-            // read the attributes name='value'
1758
-            $prop = "([a-zA-Z0-9_]+)=[']([^']*)[']";
1759
-            preg_match_all('/'.$prop.'/is', $code, $match);
1760
-            for ($k=0; $k<count($match[0]); $k++) {
1761
-                $tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1762
-            }
1763
-
1764
-            // if type text/css => we keep it
1765
-            if (isset($tmp['type']) && strtolower($tmp['type'])=='text/css' && isset($tmp['href'])) {
1766
-
1767
-                // get the href
1768
-                $url = $tmp['href'];
1769
-
1770
-                // get the content of the css file
1771
-                $content = @file_get_contents($url);
1772
-
1773
-                // if "http://" in the url
1774
-                if (strpos($url, 'http://')!==false) {
1775
-
1776
-                    // get the domain "http://xxx/"
1777
-                    $url = str_replace('http://', '', $url);
1778
-                    $url = explode('/', $url);
1779
-                    $urlMain = 'http://'.$url[0].'/';
1780
-
1781
-                    // get the absolute url of the path
1782
-                    $urlSelf = $url; unset($urlSelf[count($urlSelf)-1]); $urlSelf = 'http://'.implode('/', $urlSelf).'/';
1783
-
1784
-                    // adapt the url in the css content
1785
-                    $content = preg_replace('/url\(([^\\\\][^)]*)\)/isU', 'url('.$urlSelf.'$1)', $content);
1786
-                    $content = preg_replace('/url\((\\\\[^)]*)\)/isU', 'url('.$urlMain.'$1)', $content);
1787
-                } else {
14
+	/**
15
+	 * reference to the pdf object
16
+	 * @var TCPDF
17
+	 */
18
+	protected $_pdf         = null;
19
+
20
+	protected $_htmlColor   = array(); // list of the HTML colors
21
+	protected $_onlyLeft    = false;   // flag if we are in a sub html => only "text-align:left" is used
22
+	protected $_defaultFont = null;    // default font to use if the asked font does not exist
23
+
24
+	public    $value        = array(); // current values
25
+	public    $css          = array(); // css values
26
+	public    $cssKeys      = array(); // css key, for the execution order
27
+	public    $table        = array(); // level history
28
+
29
+	/**
30
+	 * Constructor
31
+	 *
32
+	 * @param  &HTML2PDF_myPdf reference to the PDF $object
33
+	 * @access public
34
+	 */
35
+	public function __construct(&$pdf)
36
+	{
37
+		$this->_init();
38
+		$this->setPdfParent($pdf);
39
+	}
40
+
41
+	/**
42
+	 * Set the HTML2PDF parent object
43
+	 *
44
+	 * @param  &HTML2PDF reference to the HTML2PDF parent $object
45
+	 * @access public
46
+	 */
47
+	public function setPdfParent(&$pdf)
48
+	{
49
+		$this->_pdf = &$pdf;
50
+	}
51
+
52
+	/**
53
+	 * Inform that we want only "test-align:left" because we are in a sub HTML
54
+	 *
55
+	 * @access public
56
+	 */
57
+	public function setOnlyLeft()
58
+	{
59
+		$this->value['text-align'] = 'left';
60
+		$this->_onlyLeft = true;
61
+	}
62
+
63
+	/**
64
+	 * Get the vales of the parent, if exist
65
+	 *
66
+	 * @return array CSS values
67
+	 * @access public
68
+	 */
69
+	public function getOldValues()
70
+	{
71
+		return isset($this->table[count($this->table)-1]) ? $this->table[count($this->table)-1] : $this->value;
72
+	}
73
+
74
+	/**
75
+	 * define the Default Font to use, if the font does not exist, or if no font asked
76
+	 *
77
+	 * @param  string  default font-family. If null : Arial for no font asked, and error fot ont does not exist
78
+	 * @return string  old default font-family
79
+	 * @access public
80
+	 */
81
+	public function setDefaultFont($default = null)
82
+	{
83
+		$old = $this->_defaultFont;
84
+		$this->_defaultFont = $default;
85
+		if ($default) $this->value['font-family'] = $default;
86
+		return $old;
87
+	}
88
+
89
+	 /**
90
+	  * Init the object
91
+	  *
92
+	  * @access protected
93
+	  */
94
+	protected function _init()
95
+	{
96
+		// get the Web Colors from TCPDF
97
+		require(K_PATH_MAIN.'htmlcolors.php');
98
+		$this->_htmlColor = $webcolor;
99
+
100
+		// init the Style
101
+		$this->table = array();
102
+		$this->value = array();
103
+		$this->initStyle();
104
+
105
+		// Init the styles without legacy
106
+		$this->resetStyle();
107
+	}
108
+
109
+	/**
110
+	 * Init the CSS Style
111
+	 *
112
+	 * @access public
113
+	 */
114
+	public function initStyle()
115
+	{
116
+		$this->value['id_tag']       = 'body';        // tag name
117
+		$this->value['id_name']          = null;         // tag - attribute name
118
+		$this->value['id_id']            = null;         // tag - attribute id
119
+		$this->value['id_class']         = null;         // tag - attribute class
120
+		$this->value['id_lst']           = array('*');   // tag - list of legacy
121
+		$this->value['mini-size']        = 1.;           // specific size report for sup, sub
122
+		$this->value['mini-decal']       = 0;            // specific position report for sup, sub
123
+		$this->value['font-family']      = 'Arial';
124
+		$this->value['font-bold']        = false;
125
+		$this->value['font-italic']      = false;
126
+		$this->value['font-underline']   = false;
127
+		$this->value['font-overline']    = false;
128
+		$this->value['font-linethrough'] = false;
129
+		$this->value['text-transform']   = 'none';
130
+		$this->value['font-size']        = $this->convertToMM('10pt');
131
+		$this->value['text-indent']      = 0;
132
+		$this->value['text-align']       = 'left';
133
+		$this->value['vertical-align']   = 'middle';
134
+		$this->value['line-height']      = 'normal';
135
+
136
+		$this->value['position']         = null;
137
+		$this->value['x']                = null;
138
+		$this->value['y']                = null;
139
+		$this->value['width']            = 0;
140
+		$this->value['height']           = 0;
141
+		$this->value['top']              = null;
142
+		$this->value['right']            = null;
143
+		$this->value['bottom']           = null;
144
+		$this->value['left']             = null;
145
+		$this->value['float']            = null;
146
+		$this->value['display']          = null;
147
+		$this->value['rotate']           = null;
148
+		$this->value['overflow']         = 'visible';
149
+
150
+		$this->value['color']            = array(0, 0, 0);
151
+		$this->value['background']       = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
152
+		$this->value['border']           = array();
153
+		$this->value['padding']          = array();
154
+		$this->value['margin']           = array();
155
+		$this->value['margin-auto']      = false;
156
+
157
+		$this->value['list-style-type']  = '';
158
+		$this->value['list-style-image'] = '';
159
+
160
+		$this->value['xc'] = null;
161
+		$this->value['yc'] = null;
162
+	}
163
+
164
+	/**
165
+	 * Init the CSS Style without legacy
166
+	 *
167
+	 * @param  string  tag name
168
+	 * @access public
169
+	 */
170
+	public function resetStyle($tagName = '')
171
+	{
172
+		// prepare somme values
173
+		$border = $this->readBorder('solid 1px #000000');
174
+		$units = array(
175
+			'1px' => $this->convertToMM('1px'),
176
+			'5px' => $this->convertToMM('5px'),
177
+		);
178
+
179
+
180
+		// prepare the Collapse attribute
181
+		$collapse = isset($this->value['border']['collapse']) ? $this->value['border']['collapse'] : false;
182
+		if (!in_array($tagName, array('tr', 'td', 'th', 'thead', 'tbody', 'tfoot'))) $collapse = false;
183
+
184
+		// set the global css values
185
+		$this->value['position']   = null;
186
+		$this->value['x']          = null;
187
+		$this->value['y']          = null;
188
+		$this->value['width']      = 0;
189
+		$this->value['height']     = 0;
190
+		$this->value['top']        = null;
191
+		$this->value['right']      = null;
192
+		$this->value['bottom']     = null;
193
+		$this->value['left']       = null;
194
+		$this->value['float']      = null;
195
+		$this->value['display']    = null;
196
+		$this->value['rotate']     = null;
197
+		$this->value['overflow']   = 'visible';
198
+		$this->value['background'] = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
199
+		$this->value['border']     = array(
200
+			't' => $this->readBorder('none'),
201
+			'r' => $this->readBorder('none'),
202
+			'b' => $this->readBorder('none'),
203
+			'l' => $this->readBorder('none'),
204
+			'radius' => array(
205
+				'tl' => array(0, 0),
206
+				'tr' => array(0, 0),
207
+				'br' => array(0, 0),
208
+				'bl' => array(0, 0)
209
+			),
210
+			'collapse' => $collapse,
211
+		);
212
+
213
+		// specific values for some tags
214
+		if (!in_array($tagName, array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) {
215
+			$this->value['margin'] = array('t'=>0,'r'=>0,'b'=>0,'l'=>0);
216
+		}
217
+
218
+		if (in_array($tagName, array('input', 'select', 'textarea'))) {
219
+			$this->value['border']['t'] = null;
220
+			$this->value['border']['r'] = null;
221
+			$this->value['border']['b'] = null;
222
+			$this->value['border']['l'] = null;
223
+		}
224
+
225
+		if ($tagName=='p') {
226
+			$this->value['margin']['t'] = null;
227
+			$this->value['margin']['b'] = null;
228
+		}
229
+		if ($tagName=='blockquote') {
230
+			$this->value['margin']['t'] = 3;
231
+			$this->value['margin']['r'] = 3;
232
+			$this->value['margin']['b'] = 3;
233
+			$this->value['margin']['l'] = 6;
234
+		}
235
+		$this->value['margin-auto'] = false;
236
+
237
+		if (in_array($tagName, array('blockquote', 'div', 'fieldset'))) {
238
+			$this->value['vertical-align'] = 'top';
239
+		}
240
+
241
+		if (in_array($tagName, array('fieldset', 'legend'))) {
242
+			$this->value['border'] = array(
243
+				't' => $border,
244
+				'r' => $border,
245
+				'b' => $border,
246
+				'l' => $border,
247
+				'radius' => array(
248
+					'tl' => array($units['5px'], $units['5px']),
249
+					'tr' => array($units['5px'], $units['5px']),
250
+					'br' => array($units['5px'], $units['5px']),
251
+					'bl' => array($units['5px'], $units['5px'])
252
+				),
253
+				'collapse' => false,
254
+			);
255
+		}
256
+
257
+		if (in_array($tagName, array('ul', 'li'))) {
258
+			$this->value['list-style-type']  = '';
259
+			$this->value['list-style-image'] = '';
260
+		}
261
+
262
+		if (!in_array($tagName, array('tr', 'td'))) {
263
+			$this->value['padding'] = array(
264
+				't' => 0,
265
+				'r' => 0,
266
+				'b' => 0,
267
+				'l' => 0
268
+			);
269
+		} else {
270
+			$this->value['padding'] = array(
271
+				't' => $units['1px'],
272
+				'r' => $units['1px'],
273
+				'b' => $units['1px'],
274
+				'l' => $units['1px']
275
+			);
276
+		}
277
+
278
+		if ($tagName=='hr') {
279
+			$this->value['border'] = array(
280
+				't' => $border,
281
+				'r' => $border,
282
+				'b' => $border,
283
+				'l' => $border,
284
+				'radius' => array(
285
+					'tl' => array(0, 0),
286
+					'tr' => array(0, 0),
287
+					'br' => array(0, 0),
288
+					'bl' => array(0, 0)
289
+				),
290
+				'collapse' => false,
291
+			);
292
+			$this->convertBackground('#FFFFFF', $this->value['background']);
293
+		}
294
+
295
+		$this->value['xc'] = null;
296
+		$this->value['yc'] = null;
297
+	}
298
+
299
+	/**
300
+	 * Init the PDF Font
301
+	 *
302
+	 * @access public
303
+	 */
304
+	public function fontSet()
305
+	{
306
+		$family = strtolower($this->value['font-family']);
307
+
308
+		$b = ($this->value['font-bold']        ? 'B' : '');
309
+		$i = ($this->value['font-italic']      ? 'I' : '');
310
+		$u = ($this->value['font-underline']   ? 'U' : '');
311
+		$d = ($this->value['font-linethrough'] ? 'D' : '');
312
+		$o = ($this->value['font-overline']    ? 'O' : '');
313
+
314
+		// font style
315
+		$style = $b.$i;
316
+
317
+		if ($this->_defaultFont) {
318
+			if($family=='arial')
319
+				$family='helvetica';
320
+			elseif($family=='symbol' || $family=='zapfdingbats')
321
+				$style='';
322
+
323
+			$fontkey = $family.$style;
324
+			if (!$this->_pdf->isLoadedFont($fontkey))
325
+				$family = $this->_defaultFont;
326
+		}
327
+
328
+		if($family=='arial')
329
+			$family='helvetica';
330
+		elseif($family=='symbol' || $family=='zapfdingbats')
331
+			$style='';
332
+
333
+		// complete style
334
+		$style.= $u.$d.$o;
335
+
336
+		// size : mm => pt
337
+		$size = $this->value['font-size'];
338
+		$size = 72 * $size / 25.4;
339
+
340
+		// apply the font
341
+		$this->_pdf->SetFont($family, $style, $this->value['mini-size']*$size);
342
+		$this->_pdf->setTextColorArray($this->value['color']);
343
+		if ($this->value['background']['color'])
344
+			$this->_pdf->setFillColorArray($this->value['background']['color']);
345
+		else
346
+			$this->_pdf->setFillColor(255);
347
+	}
348
+
349
+	 /**
350
+	  * add a level in the CSS history
351
+	  *
352
+	  * @access public
353
+	  */
354
+	public function save()
355
+	{
356
+		array_push($this->table, $this->value);
357
+	}
358
+
359
+	 /**
360
+	  * remove a level in the CSS history
361
+	  *
362
+	  * @access public
363
+	  */
364
+	public function load()
365
+	{
366
+		if (count($this->table)) {
367
+			$this->value = array_pop($this->table);
368
+		}
369
+	}
370
+
371
+	 /**
372
+	  * restore the Y positiony (used after a span)
373
+	  *
374
+	  * @access public
375
+	  */
376
+	public function restorePosition()
377
+	{
378
+		if ($this->value['y']==$this->_pdf->getY()) $this->_pdf->setY($this->value['yc'], false);
379
+	}
380
+
381
+	 /**
382
+	  * set the New position for the current Tag
383
+	  *
384
+	  * @access public
385
+	  */
386
+	public function setPosition()
387
+	{
388
+		// get the current position
389
+		$currentX = $this->_pdf->getX();
390
+		$currentY = $this->_pdf->getY();
391
+
392
+		// save it
393
+		$this->value['xc'] = $currentX;
394
+		$this->value['yc'] = $currentY;
395
+
396
+		if ($this->value['position']=='relative' || $this->value['position']=='absolute') {
397
+			if ($this->value['right']!==null) {
398
+				$x = $this->getLastWidth(true) - $this->value['right'] - $this->value['width'];
399
+				if ($this->value['margin']['r']) $x-= $this->value['margin']['r'];
400
+			} else {
401
+				$x = $this->value['left'];
402
+				if ($this->value['margin']['l']) $x+= $this->value['margin']['l'];
403
+			}
404
+
405
+			if ($this->value['bottom']!==null) {
406
+				$y = $this->getLastHeight(true) - $this->value['bottom'] - $this->value['height'];
407
+				if ($this->value['margin']['b']) $y-= $this->value['margin']['b'];
408
+			} else {
409
+				$y = $this->value['top'];
410
+				if ($this->value['margin']['t']) $y+= $this->value['margin']['t'];
411
+			}
412
+
413
+			if ($this->value['position']=='relative') {
414
+				$this->value['x'] = $currentX + $x;
415
+				$this->value['y'] = $currentY + $y;
416
+			} else {
417
+				$this->value['x'] = $this->_getLastAbsoluteX()+$x;
418
+				$this->value['y'] = $this->_getLastAbsoluteY()+$y;
419
+			}
420
+		} else {
421
+			$this->value['x'] = $currentX;
422
+			$this->value['y'] = $currentY;
423
+			if ($this->value['margin']['l']) $this->value['x']+= $this->value['margin']['l'];
424
+			if ($this->value['margin']['t']) $this->value['y']+= $this->value['margin']['t'];
425
+		}
426
+
427
+		// save the new position
428
+		$this->_pdf->setXY($this->value['x'], $this->value['y']);
429
+	}
430
+
431
+	 /**
432
+	  * Analise the CSS style to convert it into Form style
433
+	  *
434
+	  * @access public
435
+	  * @param  array    styles
436
+	  */
437
+	public function getFormStyle()
438
+	{
439
+		$prop = array();
440
+
441
+		$prop['alignment'] = $this->value['text-align'];
442
+
443
+		if (isset($this->value['background']['color']) && is_array($this->value['background']['color'])) {
444
+			$prop['fillColor'] = $this->value['background']['color'];
445
+		}
446
+
447
+		if (isset($this->value['border']['t']['color'])) {
448
+			$prop['strokeColor'] = $this->value['border']['t']['color'];
449
+		}
450
+
451
+		if (isset($this->value['border']['t']['width'])) {
452
+			$prop['lineWidth'] = $this->value['border']['t']['width'];
453
+		}
454
+
455
+		if (isset($this->value['border']['t']['type'])) {
456
+			$prop['borderStyle'] = $this->value['border']['t']['type'];
457
+		}
458
+
459
+		if (!empty($this->value['color'])) {
460
+			$prop['textColor'] = $this->value['color'];
461
+		}
462
+
463
+		if (!empty($this->value['font-size'])) {
464
+			$prop['textSize'] = $this->value['font-size'];
465
+		}
466
+
467
+		return $prop;
468
+	}
469
+
470
+	 /**
471
+	  * Analise the CSS style to convert it into SVG style
472
+	  *
473
+	  * @access public
474
+	  * @param  string   tag name
475
+	  * @param  array    styles
476
+	  */
477
+	public function getSvgStyle($tagName, &$param)
478
+	{
479
+		// prepare
480
+		$tagName = strtolower($tagName);
481
+		$id   = isset($param['id'])   ? strtolower(trim($param['id']))   : null; if (!$id)   $id   = null;
482
+		$name = isset($param['name']) ? strtolower(trim($param['name'])) : null; if (!$name) $name = null;
483
+
484
+		// read the class attribute
485
+		$class = array();
486
+		$tmp = isset($param['class']) ? strtolower(trim($param['class'])) : '';
487
+		$tmp = explode(' ', $tmp);
488
+		foreach ($tmp as $k => $v) {
489
+			$v = trim($v);
490
+			if ($v) $class[] = $v;
491
+		}
492
+
493
+		// identify the tag, and the direct styles
494
+		$this->value['id_tag'] = $tagName;
495
+		$this->value['id_name']   = $name;
496
+		$this->value['id_id']     = $id;
497
+		$this->value['id_class']  = $class;
498
+		$this->value['id_lst']    = array();
499
+		$this->value['id_lst'][] = '*';
500
+		$this->value['id_lst'][] = $tagName;
501
+		if (!isset($this->value['svg'])) {
502
+			$this->value['svg'] = array(
503
+				'stroke'         => null,
504
+				'stroke-width'   => $this->convertToMM('1pt'),
505
+				'fill'           => null,
506
+				'fill-opacity'   => null,
507
+			);
508
+		}
509
+
510
+		if (count($class)) {
511
+			foreach ($class as $v) {
512
+				$this->value['id_lst'][] = '*.'.$v;
513
+				$this->value['id_lst'][] = '.'.$v;
514
+				$this->value['id_lst'][] = $tagName.'.'.$v;
515
+			}
516
+		}
517
+		if ($id) {
518
+			$this->value['id_lst'][] = '*#'.$id;
519
+			$this->value['id_lst'][] = '#'.$id;
520
+			$this->value['id_lst'][] = $tagName.'#'.$id;
521
+		}
522
+
523
+		// CSS style
524
+		$styles = $this->_getFromCSS();
525
+
526
+		// adding the style from the tag
527
+		$styles = array_merge($styles, $param['style']);
528
+
529
+		if (isset($styles['stroke']))        $this->value['svg']['stroke']       = $this->convertToColor($styles['stroke'], $res);
530
+		if (isset($styles['stroke-width']))  $this->value['svg']['stroke-width'] = $this->convertToMM($styles['stroke-width']);
531
+		if (isset($styles['fill']))          $this->value['svg']['fill']         = $this->convertToColor($styles['fill'], $res);
532
+		if (isset($styles['fill-opacity']))  $this->value['svg']['fill-opacity'] = 1.*$styles['fill-opacity'];
533
+
534
+		return $this->value['svg'];
535
+	}
536
+
537
+	/**
538
+	 * analyse the css properties from the HTML parsing
539
+	 *
540
+	 * @access public
541
+	 * @param  string  $tagName
542
+	 * @param  array   $param
543
+	 * @param  array   $legacy
544
+	 */
545
+	public function analyse($tagName, &$param, $legacy = null)
546
+	{
547
+		// prepare the informations
548
+		$tagName = strtolower($tagName);
549
+		$id   = isset($param['id'])   ? strtolower(trim($param['id']))    : null; if (!$id)   $id   = null;
550
+		$name = isset($param['name']) ? strtolower(trim($param['name']))  : null; if (!$name) $name = null;
551
+
552
+		// get the class names to use
553
+		$class = array();
554
+		$tmp = isset($param['class']) ? strtolower(trim($param['class'])) : '';
555
+		$tmp = explode(' ', $tmp);
556
+		foreach ($tmp as $k => $v) {
557
+			$v = trim($v);
558
+			if ($v) $class[] = $v;
559
+		}
560
+
561
+		// prepare the values, and the list of css tags to identify
562
+		$this->value['id_tag']   = $tagName;
563
+		$this->value['id_name']  = $name;
564
+		$this->value['id_id']    = $id;
565
+		$this->value['id_class'] = $class;
566
+		$this->value['id_lst']   = array();
567
+		$this->value['id_lst'][] = '*';
568
+		$this->value['id_lst'][] = $tagName;
569
+		if (count($class)) {
570
+			foreach ($class as $v) {
571
+				$this->value['id_lst'][] = '*.'.$v;
572
+				$this->value['id_lst'][] = '.'.$v;
573
+				$this->value['id_lst'][] = $tagName.'.'.$v;
574
+			}
575
+		}
576
+		if ($id) {
577
+			$this->value['id_lst'][] = '*#'.$id;
578
+			$this->value['id_lst'][] = '#'.$id;
579
+			$this->value['id_lst'][] = $tagName.'#'.$id;
580
+		}
581
+
582
+		// get the css styles from class
583
+		$styles = $this->_getFromCSS();
584
+
585
+		// merge with the css styles from tag
586
+		$styles = array_merge($styles, $param['style']);
587
+		if (isset($param['allwidth']) && !isset($styles['width'])) $styles['width'] = '100%';
588
+
589
+		// reset some styles, depending on the tag name
590
+		$this->resetStyle($tagName);
591
+
592
+		// add the legacy values
593
+		if ($legacy) {
594
+			foreach ($legacy as $legacyName => $legacyValue) {
595
+				if (is_array($legacyValue)) {
596
+					foreach($legacyValue as $legacy2Name => $legacy2Value)
597
+						$this->value[$legacyName][$legacy2Name] = $legacy2Value;
598
+				} else {
599
+					$this->value[$legacyName] = $legacyValue;
600
+				}
601
+			}
602
+		}
603
+
604
+		// some flags
605
+		$correctWidth = false;
606
+		$noWidth = true;
607
+
608
+		// read all the css styles
609
+		foreach ($styles as $nom => $val) {
610
+			switch($nom)
611
+			{
612
+				case 'font-family':
613
+					$val = explode(',', $val);
614
+					$val = trim($val[0]);
615
+					if ($val) $this->value['font-family'] = $val;
616
+					break;
617
+
618
+				case 'font-weight':
619
+					$this->value['font-bold'] = ($val=='bold');
620
+					break;
621
+
622
+				case 'font-style':
623
+					$this->value['font-italic'] = ($val=='italic');
624
+					break;
625
+
626
+				case 'text-decoration':
627
+					$val = explode(' ', $val);
628
+					$this->value['font-underline']   = (in_array('underline', $val));
629
+					$this->value['font-overline']    = (in_array('overline', $val));
630
+					$this->value['font-linethrough'] = (in_array('line-through', $val));
631
+					break;
632
+
633
+				case 'text-indent':
634
+					$this->value['text-indent'] = $this->convertToMM($val);
635
+					break;
636
+
637
+				case 'text-transform':
638
+					if (!in_array($val, array('none', 'capitalize', 'uppercase', 'lowercase'))) $val = 'none';
639
+					$this->value['text-transform']  = $val;
640
+					break;
641
+
642
+				case 'font-size':
643
+					$val = $this->convertToMM($val, $this->value['font-size']);
644
+					if ($val) $this->value['font-size'] = $val;
645
+					break;
646
+
647
+				case 'color':
648
+					$res = null;
649
+					$this->value['color'] = $this->convertToColor($val, $res);
650
+					if ($tagName=='hr') {
651
+						$this->value['border']['l']['color'] = $this->value['color'];
652
+						$this->value['border']['t']['color'] = $this->value['color'];
653
+						$this->value['border']['r']['color'] = $this->value['color'];
654
+						$this->value['border']['b']['color'] = $this->value['color'];
655
+					}
656
+					break;
657
+
658
+				case 'text-align':
659
+					$val = strtolower($val);
660
+					if (!in_array($val, array('left', 'right', 'center', 'justify', 'li_right'))) $val = 'left';
661
+					$this->value['text-align'] = $val;
662
+					break;
663
+
664
+				case 'vertical-align':
665
+					$this->value['vertical-align'] = $val;
666
+					break;
667
+
668
+				case 'width':
669
+					$this->value['width'] = $this->convertToMM($val, $this->getLastWidth());
670
+					if ($this->value['width'] && substr($val, -1)=='%') $correctWidth=true;
671
+					$noWidth = false;
672
+					break;
673
+
674
+				case 'height':
675
+					$this->value['height'] = $this->convertToMM($val, $this->getLastHeight());
676
+					break;
677
+
678
+				case 'line-height':
679
+					if (preg_match('/^[0-9\.]+$/isU', $val)) $val = floor($val*100).'%';
680
+					$this->value['line-height'] = $val;
681
+					break;
682
+
683
+				case 'rotate':
684
+					if (!in_array($val, array(0, -90, 90, 180, 270, -180, -270))) $val = null;
685
+					if ($val<0) $val+= 360;
686
+					$this->value['rotate'] = $val;
687
+					break;
688
+
689
+				case 'overflow':
690
+					if (!in_array($val, array('visible', 'hidden'))) $val = 'visible';
691
+					$this->value['overflow'] = $val;
692
+					break;
693
+
694
+				case 'padding':
695
+					$val = explode(' ', $val);
696
+					foreach ($val as $k => $v) {
697
+						$v = trim($v);
698
+						if ($v!='') {
699
+							$val[$k] = $v;
700
+						} else {
701
+							unset($val[$k]);
702
+						}
703
+					}
704
+					$val = array_values($val);
705
+					$this->_duplicateBorder($val);
706
+					$this->value['padding']['t'] = $this->convertToMM($val[0], 0);
707
+					$this->value['padding']['r'] = $this->convertToMM($val[1], 0);
708
+					$this->value['padding']['b'] = $this->convertToMM($val[2], 0);
709
+					$this->value['padding']['l'] = $this->convertToMM($val[3], 0);
710
+					break;
711
+
712
+				case 'padding-top':
713
+					$this->value['padding']['t'] = $this->convertToMM($val, 0);
714
+					break;
715
+
716
+				case 'padding-right':
717
+					$this->value['padding']['r'] = $this->convertToMM($val, 0);
718
+					break;
719
+
720
+				case 'padding-bottom':
721
+					$this->value['padding']['b'] = $this->convertToMM($val, 0);
722
+					break;
723
+
724
+				case 'padding-left':
725
+					$this->value['padding']['l'] = $this->convertToMM($val, 0);
726
+					break;
727
+
728
+				case 'margin':
729
+					if ($val=='auto') {
730
+						$this->value['margin-auto'] = true;
731
+						break;
732
+					}
733
+					$val = explode(' ', $val);
734
+					foreach ($val as $k => $v) {
735
+						$v = trim($v);
736
+						if ($v!='') {
737
+							$val[$k] = $v;
738
+						} else {
739
+							unset($val[$k]);
740
+						}
741
+					}
742
+					$val = array_values($val);
743
+					$this->_duplicateBorder($val);
744
+					$this->value['margin']['t'] = $this->convertToMM($val[0], 0);
745
+					$this->value['margin']['r'] = $this->convertToMM($val[1], 0);
746
+					$this->value['margin']['b'] = $this->convertToMM($val[2], 0);
747
+					$this->value['margin']['l'] = $this->convertToMM($val[3], 0);
748
+					break;
749
+
750
+				case 'margin-top':
751
+					$this->value['margin']['t'] = $this->convertToMM($val, 0);
752
+					break;
753
+
754
+				case 'margin-right':
755
+					$this->value['margin']['r'] = $this->convertToMM($val, 0);
756
+					break;
757
+
758
+				case 'margin-bottom':
759
+					$this->value['margin']['b'] = $this->convertToMM($val, 0);
760
+					break;
761
+
762
+				case 'margin-left':
763
+					$this->value['margin']['l'] = $this->convertToMM($val, 0);
764
+					break;
765
+
766
+				case 'border':
767
+					$val = $this->readBorder($val);
768
+					$this->value['border']['t'] = $val;
769
+					$this->value['border']['r'] = $val;
770
+					$this->value['border']['b'] = $val;
771
+					$this->value['border']['l'] = $val;
772
+					break;
773
+
774
+				case 'border-style':
775
+					$val = explode(' ', $val);
776
+					foreach ($val as $valK => $valV) {
777
+						if (!in_array($valV, array('solid', 'dotted', 'dashed'))) {
778
+							$val[$valK] = null;
779
+						}
780
+					}
781
+					$this->_duplicateBorder($val);
782
+					if ($val[0]) $this->value['border']['t']['type'] = $val[0];
783
+					if ($val[1]) $this->value['border']['r']['type'] = $val[1];
784
+					if ($val[2]) $this->value['border']['b']['type'] = $val[2];
785
+					if ($val[3]) $this->value['border']['l']['type'] = $val[3];
786
+					break;
787
+
788
+				case 'border-top-style':
789
+					if (in_array($val, array('solid', 'dotted', 'dashed'))) {
790
+						$this->value['border']['t']['type'] = $val;
791
+					}
792
+					break;
793
+
794
+				case 'border-right-style':
795
+					if (in_array($val, array('solid', 'dotted', 'dashed'))) {
796
+						$this->value['border']['r']['type'] = $val;
797
+					}
798
+					break;
799
+
800
+				case 'border-bottom-style':
801
+					if (in_array($val, array('solid', 'dotted', 'dashed'))) {
802
+						$this->value['border']['b']['type'] = $val;
803
+					}
804
+					break;
805
+
806
+				case 'border-left-style':
807
+					if (in_array($val, array('solid', 'dotted', 'dashed')))
808
+						$this->value['border']['l']['type'] = $val;
809
+					break;
810
+
811
+				case 'border-color':
812
+					$res = false;
813
+					$val = preg_replace('/,[\s]+/', ',', $val);
814
+					$val = explode(' ', $val);
815
+					foreach ($val as $valK => $valV) {
816
+							$val[$valK] = $this->convertToColor($valV, $res);
817
+							if (!$res) {
818
+								$val[$valK] = null;
819
+							}
820
+					}
821
+					$this->_duplicateBorder($val);
822
+					if (is_array($val[0])) $this->value['border']['t']['color'] = $val[0];
823
+					if (is_array($val[1])) $this->value['border']['r']['color'] = $val[1];
824
+					if (is_array($val[2])) $this->value['border']['b']['color'] = $val[2];
825
+					if (is_array($val[3])) $this->value['border']['l']['color'] = $val[3];
826
+
827
+					break;
828
+
829
+				case 'border-top-color':
830
+					$res = false;
831
+					$val = $this->convertToColor($val, $res);
832
+					if ($res) $this->value['border']['t']['color'] = $val;
833
+					break;
834
+
835
+				case 'border-right-color':
836
+					$res = false;
837
+					$val = $this->convertToColor($val, $res);
838
+					if ($res) $this->value['border']['r']['color'] = $val;
839
+					break;
840
+
841
+				case 'border-bottom-color':
842
+					$res = false;
843
+					$val = $this->convertToColor($val, $res);
844
+					if ($res) $this->value['border']['b']['color'] = $val;
845
+					break;
846
+
847
+				case 'border-left-color':
848
+					$res = false;
849
+					$val = $this->convertToColor($val, $res);
850
+					if ($res) $this->value['border']['l']['color'] = $val;
851
+					break;
852
+
853
+				case 'border-width':
854
+					$val = explode(' ', $val);
855
+					foreach ($val as $valK => $valV) {
856
+							$val[$valK] = $this->convertToMM($valV, 0);
857
+					}
858
+					$this->_duplicateBorder($val);
859
+					if ($val[0]) $this->value['border']['t']['width'] = $val[0];
860
+					if ($val[1]) $this->value['border']['r']['width'] = $val[1];
861
+					if ($val[2]) $this->value['border']['b']['width'] = $val[2];
862
+					if ($val[3]) $this->value['border']['l']['width'] = $val[3];
863
+					break;
864
+
865
+				case 'border-top-width':
866
+					$val = $this->convertToMM($val, 0);
867
+					if ($val) $this->value['border']['t']['width'] = $val;
868
+					break;
869
+
870
+				case 'border-right-width':
871
+					$val = $this->convertToMM($val, 0);
872
+					if ($val) $this->value['border']['r']['width'] = $val;
873
+					break;
874
+
875
+				case 'border-bottom-width':
876
+					$val = $this->convertToMM($val, 0);
877
+					if ($val) $this->value['border']['b']['width'] = $val;
878
+					break;
879
+
880
+				case 'border-left-width':
881
+					$val = $this->convertToMM($val, 0);
882
+					if ($val) $this->value['border']['l']['width'] = $val;
883
+					break;
884
+
885
+				case 'border-collapse':
886
+					if ($tagName=='table') $this->value['border']['collapse'] = ($val=='collapse');
887
+					break;
888
+
889
+				case 'border-radius':
890
+					$val = explode('/', $val);
891
+					if (count($val)>2) {
892
+						break;
893
+					}
894
+					$valH = $this->convertToRadius(trim($val[0]));
895
+					if (count($valH)<1 || count($valH)>4) {
896
+						break;
897
+					}
898
+					if (!isset($valH[1])) $valH[1] = $valH[0];
899
+					if (!isset($valH[2])) $valH = array($valH[0], $valH[0], $valH[1], $valH[1]);
900
+					if (!isset($valH[3])) $valH[3] = $valH[1];
901
+					if (isset($val[1])) {
902
+						$valV = $this->convertToRadius(trim($val[1]));
903
+						if (count($valV)<1 || count($valV)>4) {
904
+							break;
905
+						}
906
+						if (!isset($valV[1])) $valV[1] = $valV[0];
907
+						if (!isset($valV[2])) $valV = array($valV[0], $valV[0], $valV[1], $valV[1]);
908
+						if (!isset($valV[3])) $valV[3] = $valV[1];
909
+					} else {
910
+						$valV = $valH;
911
+					}
912
+					$this->value['border']['radius'] = array(
913
+								'tl' => array($valH[0], $valV[0]),
914
+								'tr' => array($valH[1], $valV[1]),
915
+								'br' => array($valH[2], $valV[2]),
916
+								'bl' => array($valH[3], $valV[3])
917
+							);
918
+					break;
919
+
920
+				case 'border-top-left-radius':
921
+					$val = $this->convertToRadius($val);
922
+					if (count($val)<1 || count($val)>2) {
923
+						break;
924
+					}
925
+					$this->value['border']['radius']['tl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
926
+					break;
927
+
928
+				case 'border-top-right-radius':
929
+					$val = $this->convertToRadius($val);
930
+					if (count($val)<1 || count($val)>2) {
931
+						break;
932
+					}
933
+					$this->value['border']['radius']['tr'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
934
+					break;
935
+
936
+				case 'border-bottom-right-radius':
937
+					$val = $this->convertToRadius($val);
938
+					if (count($val)<1 || count($val)>2) {
939
+						break;
940
+					}
941
+					$this->value['border']['radius']['br'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
942
+					break;
943
+
944
+				case 'border-bottom-left-radius':
945
+					$val = $this->convertToRadius($val);
946
+					if (count($val)<1 || count($val)>2) {
947
+						break;
948
+					}
949
+					$this->value['border']['radius']['bl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
950
+					break;
951
+
952
+				case 'border-top':
953
+					$this->value['border']['t'] = $this->readBorder($val);
954
+					break;
955
+
956
+				case 'border-right':
957
+					$this->value['border']['r'] = $this->readBorder($val);
958
+					break;
959
+
960
+				case 'border-bottom':
961
+					$this->value['border']['b'] = $this->readBorder($val);
962
+					break;
963
+
964
+				case 'border-left':
965
+					$this->value['border']['l'] = $this->readBorder($val);
966
+					break;
967
+
968
+				case 'background-color':
969
+					$this->value['background']['color'] = $this->convertBackgroundColor($val);
970
+					break;
971
+
972
+				case 'background-image':
973
+					$this->value['background']['image'] = $this->convertBackgroundImage($val);
974
+					break;
975
+
976
+				case 'background-position':
977
+					$res = null;
978
+					$this->value['background']['position'] = $this->convertBackgroundPosition($val, $res);
979
+					break;
980
+
981
+				case 'background-repeat':
982
+					$this->value['background']['repeat'] = $this->convertBackgroundRepeat($val);
983
+					break;
984
+
985
+				case 'background':
986
+					$this->convertBackground($val, $this->value['background']);
987
+					break;
988
+
989
+				case 'position':
990
+					if ($val=='absolute')       $this->value['position'] = 'absolute';
991
+					else if ($val=='relative')  $this->value['position'] = 'relative';
992
+					else                        $this->value['position'] = null;
993
+					break;
994
+
995
+				case 'float':
996
+					if ($val=='left')           $this->value['float'] = 'left';
997
+					else if ($val=='right')     $this->value['float'] = 'right';
998
+					else                        $this->value['float'] = null;
999
+					break;
1000
+
1001
+				case 'display':
1002
+					if ($val=='inline')         $this->value['display'] = 'inline';
1003
+					else if ($val=='block')     $this->value['display'] = 'block';
1004
+					else if ($val=='none')      $this->value['display'] = 'none';
1005
+					else                        $this->value['display'] = null;
1006
+					break;
1007
+
1008
+				case 'top':
1009
+				case 'bottom':
1010
+				case 'left':
1011
+				case 'right':
1012
+					$this->value[$nom] = $val;
1013
+					break;
1014
+
1015
+				case 'list-style':
1016
+				case 'list-style-type':
1017
+				case 'list-style-image':
1018
+					if ($nom=='list-style') $nom = 'list-style-type';
1019
+					$this->value[$nom] = $val;
1020
+					break;
1021
+
1022
+				default:
1023
+					break;
1024
+			}
1025
+		}
1026
+
1027
+		$return = true;
1028
+
1029
+		// only for P tag
1030
+		if ($this->value['margin']['t']===null) $this->value['margin']['t'] = $this->value['font-size'];
1031
+		if ($this->value['margin']['b']===null) $this->value['margin']['b'] = $this->value['font-size'];
1032
+
1033
+		// force the text align to left, if asked by html2pdf
1034
+		if ($this->_onlyLeft) $this->value['text-align'] = 'left';
1035
+
1036
+		// correction on the width (quick box)
1037
+		if ($noWidth && in_array($tagName, array('div', 'blockquote', 'fieldset')) && $this->value['position']!='absolute') {
1038
+			$this->value['width'] = $this->getLastWidth();
1039
+			$this->value['width']-= $this->value['margin']['l'] + $this->value['margin']['r'];
1040
+		} else {
1041
+			if ($correctWidth) {
1042
+				if (!in_array($tagName, array('table', 'div', 'blockquote', 'fieldset', 'hr'))) {
1043
+					$this->value['width']-= $this->value['padding']['l'] + $this->value['padding']['r'];
1044
+					$this->value['width']-= $this->value['border']['l']['width'] + $this->value['border']['r']['width'];
1045
+				}
1046
+				if (in_array($tagName, array('th', 'td'))) {
1047
+					$this->value['width']-= $this->convertToMM(isset($param['cellspacing']) ? $param['cellspacing'] : '2px');
1048
+					$return = false;
1049
+				}
1050
+				if ($this->value['width']<0) $this->value['width']=0;
1051
+			} else {
1052
+				if ($this->value['width']) {
1053
+					if ($this->value['border']['l']['width']) $this->value['width'] += $this->value['border']['l']['width'];
1054
+					if ($this->value['border']['r']['width']) $this->value['width'] += $this->value['border']['r']['width'];
1055
+					if ($this->value['padding']['l'])         $this->value['width'] += $this->value['padding']['l'];
1056
+					if ($this->value['padding']['r'])         $this->value['width'] += $this->value['padding']['r'];
1057
+				}
1058
+			}
1059
+		}
1060
+		if ($this->value['height']) {
1061
+			if ($this->value['border']['b']['width']) $this->value['height'] += $this->value['border']['b']['width'];
1062
+			if ($this->value['border']['t']['width']) $this->value['height'] += $this->value['border']['t']['width'];
1063
+			if ($this->value['padding']['b'])         $this->value['height'] += $this->value['padding']['b'];
1064
+			if ($this->value['padding']['t'])         $this->value['height'] += $this->value['padding']['t'];
1065
+		}
1066
+
1067
+		if ($this->value['top']!=null)      $this->value['top']     = $this->convertToMM($this->value['top'], $this->getLastHeight(true));
1068
+		if ($this->value['bottom']!=null)   $this->value['bottom']  = $this->convertToMM($this->value['bottom'], $this->getLastHeight(true));
1069
+		if ($this->value['left']!=null)     $this->value['left']    = $this->convertToMM($this->value['left'], $this->getLastWidth(true));
1070
+		if ($this->value['right']!=null)    $this->value['right']   = $this->convertToMM($this->value['right'], $this->getLastWidth(true));
1071
+
1072
+		if ($this->value['top'] && $this->value['bottom'] && $this->value['height'])    $this->value['bottom']  = null;
1073
+		if ($this->value['left'] && $this->value['right'] && $this->value['width'])     $this->value['right']   = null;
1074
+
1075
+		return $return;
1076
+	}
1077
+
1078
+	 /**
1079
+	  * get the height of the current line
1080
+	  *
1081
+	  * @access public
1082
+	  * @return float $height in mm
1083
+	  */
1084
+	public function getLineHeight()
1085
+	{
1086
+		$val = $this->value['line-height'];
1087
+		if ($val=='normal') $val = '108%';
1088
+		return $this->convertToMM($val, $this->value['font-size']);
1089
+	}
1090
+
1091
+	 /**
1092
+	  * get the width of the parent
1093
+	  *
1094
+	  * @access public
1095
+	  * @param  boolean $mode true => adding padding and border
1096
+	  * @return float $width in mm
1097
+	  */
1098
+	public function getLastWidth($mode = false)
1099
+	{
1100
+		for ($k=count($this->table)-1; $k>=0; $k--) {
1101
+			if ($this->table[$k]['width']) {
1102
+				$w = $this->table[$k]['width'];
1103
+				if ($mode) {
1104
+					$w+= $this->table[$k]['border']['l']['width'] + $this->table[$k]['padding']['l'] + 0.02;
1105
+					$w+= $this->table[$k]['border']['r']['width'] + $this->table[$k]['padding']['r'] + 0.02;
1106
+				}
1107
+				return $w;
1108
+			}
1109
+		}
1110
+		return $this->_pdf->getW() - $this->_pdf->getlMargin() - $this->_pdf->getrMargin();
1111
+	}
1112
+
1113
+	 /**
1114
+	  * get the height of the parent
1115
+	  *
1116
+	  * @access public
1117
+	  * @param  boolean $mode true => adding padding and border
1118
+	  * @return float $height in mm
1119
+	  */
1120
+	public function getLastHeight($mode = false)
1121
+	{
1122
+		for ($k=count($this->table)-1; $k>=0; $k--) {
1123
+			if ($this->table[$k]['height']) {
1124
+				$h = $this->table[$k]['height'];
1125
+				if ($mode) {
1126
+					$h+= $this->table[$k]['border']['t']['width'] + $this->table[$k]['padding']['t'] + 0.02;
1127
+					$h+= $this->table[$k]['border']['b']['width'] + $this->table[$k]['padding']['b'] + 0.02;
1128
+				}
1129
+				return $h;
1130
+			}
1131
+		}
1132
+		return $this->_pdf->getH() - $this->_pdf->gettMargin() - $this->_pdf->getbMargin();
1133
+	}
1134
+
1135
+	/**
1136
+	 * get the value of the float property
1137
+	 *
1138
+	 * @access public
1139
+	 * @return $float left/right
1140
+	 */
1141
+	public function getFloat()
1142
+	{
1143
+		if ($this->value['float']=='left')    return 'left';
1144
+		if ($this->value['float']=='right')   return 'right';
1145
+		return null;
1146
+	}
1147
+
1148
+	/**
1149
+	 * get the last value for a specific key
1150
+	 *
1151
+	 * @access public
1152
+	 * @param  string $key
1153
+	 * @return mixed
1154
+	 */
1155
+	public function getLastValue($key)
1156
+	{
1157
+		$nb = count($this->table);
1158
+		if ($nb>0) {
1159
+			return $this->table[$nb-1][$key];
1160
+		} else {
1161
+			return null;
1162
+		}
1163
+	}
1164
+
1165
+	/**
1166
+	 * get the last absolute X
1167
+	 *
1168
+	 * @access protected
1169
+	 * @return float $x
1170
+	 */
1171
+	protected function _getLastAbsoluteX()
1172
+	{
1173
+		for ($k=count($this->table)-1; $k>=0; $k--) {
1174
+			if ($this->table[$k]['x'] && $this->table[$k]['position']) return $this->table[$k]['x'];
1175
+		}
1176
+		return $this->_pdf->getlMargin();
1177
+	}
1178
+
1179
+	/**
1180
+	 * get the last absolute Y
1181
+	 *
1182
+	 * @access protected
1183
+	 * @return float $y
1184
+	 */
1185
+	protected function _getLastAbsoluteY()
1186
+	{
1187
+		for ($k=count($this->table)-1; $k>=0; $k--) {
1188
+			if ($this->table[$k]['y'] && $this->table[$k]['position']) return $this->table[$k]['y'];
1189
+		}
1190
+		return $this->_pdf->gettMargin();
1191
+	}
1192
+
1193
+	/**
1194
+	 * get the CSS properties of the current tag
1195
+	 *
1196
+	 * @access protected
1197
+	 * @return array $styles
1198
+	 */
1199
+	protected function _getFromCSS()
1200
+	{
1201
+		// styles to apply
1202
+		$styles = array();
1203
+
1204
+		// list of the selectors to get in the CSS files
1205
+		$getit  = array();
1206
+
1207
+		// get the list of the selectors of each tags
1208
+		$lst = array();
1209
+		$lst[] = $this->value['id_lst'];
1210
+		for ($i=count($this->table)-1; $i>=0; $i--) {
1211
+			$lst[] = $this->table[$i]['id_lst'];
1212
+		}
1213
+
1214
+		// foreach selectors in the CSS files, verify if it match with the list of selectors
1215
+		foreach ($this->cssKeys as $key => $num) {
1216
+			if ($this->_getReccursiveStyle($key, $lst)) {
1217
+				$getit[$key] = $num;
1218
+			}
1219
+		}
1220
+
1221
+		// if we have selectors
1222
+		if (count($getit)) {
1223
+			// get them, but in the definition order, because of priority
1224
+			asort($getit);
1225
+			foreach ($getit as $key => $val) $styles = array_merge($styles, $this->css[$key]);
1226
+		}
1227
+
1228
+		return $styles;
1229
+	}
1230
+
1231
+	/**
1232
+	 * identify if the selector $key match with the list of tag selectors
1233
+	 *
1234
+	 * @access protected
1235
+	 * @param  string   $key CSS selector to analyse
1236
+	 * @param  array    $lst list of the selectors of each tags
1237
+	 * @param  string   $next next step of parsing the selector
1238
+	 * @return boolean
1239
+	 */
1240
+	protected function _getReccursiveStyle($key, $lst, $next = null)
1241
+	{
1242
+		// if next step
1243
+		if ($next!==null) {
1244
+			// we remove this step
1245
+			if ($next) $key = trim(substr($key, 0, -strlen($next)));
1246
+			array_shift($lst);
1247
+
1248
+			// if no more step to identify => return false
1249
+			if (!count($lst)) {
1250
+				return false;
1251
+			}
1252
+		}
1253
+
1254
+		// for each selector of the current step
1255
+		foreach ($lst[0] as $name) {
1256
+			// if selector = key => ok
1257
+			if ($key==$name) {
1258
+				return true;
1259
+			}
1260
+
1261
+			// if the end of the key = the selector and the next step is ok => ok
1262
+			if (substr($key, -strlen(' '.$name))==' '.$name && $this->_getReccursiveStyle($key, $lst, $name)) {
1263
+				return true;
1264
+			}
1265
+		}
1266
+
1267
+		// if we are not in the first step, we analyse the sub steps (the pareng tag of the current tag)
1268
+		if ($next!==null && $this->_getReccursiveStyle($key, $lst, '')) {
1269
+			return true;
1270
+		}
1271
+
1272
+		// no corresponding found
1273
+		return false;
1274
+	}
1275
+
1276
+	/**
1277
+	 * Analyse a border
1278
+	 *
1279
+	 * @access  public
1280
+	 * @param   string $css css border properties
1281
+	 * @return  array  border properties
1282
+	 */
1283
+	public function readBorder($css)
1284
+	{
1285
+		// border none
1286
+		$none = array('type' => 'none', 'width' => 0, 'color' => array(0, 0, 0));
1287
+
1288
+		// default value
1289
+		$type  = 'solid';
1290
+		$width = $this->convertToMM('1pt');
1291
+		$color = array(0, 0, 0);
1292
+
1293
+		// clean up the values
1294
+		$css = explode(' ', $css);
1295
+		foreach ($css as $k => $v) {
1296
+			$v = trim($v);
1297
+			if ($v) $css[$k] = $v;
1298
+			else    unset($css[$k]);
1299
+		}
1300
+		$css = array_values($css);
1301
+
1302
+		// read the values
1303
+		$res = null;
1304
+		foreach ($css as $value) {
1305
+
1306
+			// if no border => return none
1307
+			if ($value=='none' || $value=='hidden') {
1308
+				return $none;
1309
+			}
1310
+
1311
+			// try to convert the value as a distance
1312
+			$tmp = $this->convertToMM($value);
1313
+
1314
+			// if the convert is ok => it is a width
1315
+			if ($tmp!==null) {
1316
+				$width = $tmp;
1317
+			// else, it could be the type
1318
+			} else if (in_array($value, array('solid', 'dotted', 'dashed', 'double'))) {
1319
+				$type = $value;
1320
+			// else, it could be the color
1321
+			} else {
1322
+				$tmp = $this->convertToColor($value, $res);
1323
+				if ($res) $color = $tmp;
1324
+			}
1325
+		}
1326
+
1327
+		// if no witdh => return none
1328
+		if (!$width) return $none;
1329
+
1330
+		// return the border properties
1331
+		return array('type' => $type, 'width' => $width, 'color' => $color);
1332
+	}
1333
+
1334
+	/**
1335
+	 * duplicate the borders if needed
1336
+	 *
1337
+	 * @access protected
1338
+	 * @param  &array $val
1339
+	 */
1340
+	protected function _duplicateBorder(&$val)
1341
+	{
1342
+		// 1 value => L => RTB
1343
+		if (count($val)==1) {
1344
+			$val[1] = $val[0];
1345
+			$val[2] = $val[0];
1346
+			$val[3] = $val[0];
1347
+		// 2 values => L => R & T => B
1348
+		} else if (count($val)==2) {
1349
+			$val[2] = $val[0];
1350
+			$val[3] = $val[1];
1351
+		// 3 values => T => B
1352
+		} else if (count($val)==3) {
1353
+			$val[3] = $val[1];
1354
+		}
1355
+	}
1356
+
1357
+	/**
1358
+	 * Analyse a background
1359
+	 *
1360
+	 * @access public
1361
+	 * @param  string $css css background properties
1362
+	 * @param  &array $value parsed values (by reference, because, ther is a legacy of the parent CSS properties)
1363
+	 */
1364
+	public function convertBackground($css, &$value)
1365
+	{
1366
+		// is there a image ?
1367
+		$text = '/url\(([^)]*)\)/isU';
1368
+		if (preg_match($text, $css, $match)) {
1369
+			// get the image
1370
+			$value['image'] = $this->convertBackgroundImage($match[0]);
1371
+
1372
+			// remove if from the css properties
1373
+			$css = preg_replace($text, '', $css);
1374
+			$css = preg_replace('/[\s]+/', ' ', $css);
1375
+		}
1376
+
1377
+		// protect some spaces
1378
+		$css = preg_replace('/,[\s]+/', ',', $css);
1379
+
1380
+		// explode the values
1381
+		$css = explode(' ', $css);
1382
+
1383
+		// background position to parse
1384
+		$pos = '';
1385
+
1386
+		// foreach value
1387
+		foreach ($css as $val) {
1388
+			// try to parse the value as a color
1389
+			$ok = false;
1390
+			$color = $this->convertToColor($val, $ok);
1391
+
1392
+			// if ok => it is a color
1393
+			if ($ok) {
1394
+				$value['color'] = $color;
1395
+			// else if transparent => no coloàr
1396
+			} else if ($val=='transparent') {
1397
+				$value['color'] = null;
1398
+			// else
1399
+			} else {
1400
+				// try to parse the value as a repeat
1401
+				$repeat = $this->convertBackgroundRepeat($val);
1402
+
1403
+				// if ok => it is repeat
1404
+				if ($repeat) {
1405
+					$value['repeat'] = $repeat;
1406
+				// else => it could only be a position
1407
+				} else {
1408
+					$pos.= ($pos ? ' ' : '').$val;
1409
+				}
1410
+			}
1411
+		}
1412
+
1413
+		// if we have a position to parse
1414
+		if ($pos) {
1415
+			// try to read it
1416
+			$pos = $this->convertBackgroundPosition($pos, $ok);
1417
+			if ($ok) $value['position'] = $pos;
1418
+		}
1419
+	}
1420
+
1421
+	/**
1422
+	 * parse a background color
1423
+	 *
1424
+	 * @access public
1425
+	 * @param  string $css
1426
+	 * @return string $value
1427
+	 */
1428
+	public function convertBackgroundColor($css)
1429
+	{
1430
+		$res = null;
1431
+		if ($css=='transparent') return null;
1432
+		else                     return $this->convertToColor($css, $res);
1433
+	}
1434
+
1435
+	/**
1436
+	 * parse a background image
1437
+	 *
1438
+	 * @access public
1439
+	 * @param  string $css
1440
+	 * @return string $value
1441
+	 */
1442
+	public function convertBackgroundImage($css)
1443
+	{
1444
+		if ($css=='none')
1445
+			return null;
1446
+		else if (preg_match('/^url\(([^)]*)\)$/isU', $css, $match))
1447
+			return $match[1];
1448
+		else
1449
+			return null;
1450
+	}
1451
+
1452
+	/**
1453
+	 * parse a background position
1454
+	 *
1455
+	 * @access public
1456
+	 * @param  string $css
1457
+	 * @param  &boolean $res flag if conver is ok or not
1458
+	 * @return array ($x, $y)
1459
+	 */
1460
+	public function convertBackgroundPosition($css, &$res)
1461
+	{
1462
+		// init the res
1463
+		$res = false;
1464
+
1465
+		// explode the value
1466
+		$css = explode(' ', $css);
1467
+
1468
+		// we must have 2 values. if 0 or >2 : error. if 1 => put center for 2
1469
+		if (count($css)<2) {
1470
+			if (!$css[0]) return null;
1471
+			$css[1] = 'center';
1472
+		}
1473
+		if (count($css)>2) return null;
1474
+
1475
+		// prepare the values
1476
+		$x = 0;
1477
+		$y = 0;
1478
+		$res = true;
1479
+
1480
+		// convert the first value
1481
+		if ($css[0]=='left')        $x = '0%';
1482
+		else if ($css[0]=='center') $x = '50%';
1483
+		else if ($css[0]=='right')  $x = '100%';
1484
+		else if ($css[0]=='top')    $y = '0%';
1485
+		else if ($css[0]=='bottom') $y = '100%';
1486
+		else if (preg_match('/^[-]?[0-9\.]+%$/isU', $css[0])) $x = $css[0];
1487
+		else if ($this->convertToMM($css[0])) $x = $this->convertToMM($css[0]);
1488
+		else $res = false;
1489
+
1490
+		// convert the second value
1491
+		if ($css[1]=='left')        $x = '0%';
1492
+		else if ($css[1]=='right')  $x = '100%';
1493
+		else if ($css[1]=='top')    $y = '0%';
1494
+		else if ($css[1]=='center') $y = '50%';
1495
+		else if ($css[1]=='bottom') $y = '100%';
1496
+		else if (preg_match('/^[-]?[0-9\.]+%$/isU', $css[1])) $y = $css[1];
1497
+		else if ($this->convertToMM($css[1])) $y = $this->convertToMM($css[1]);
1498
+		else $res = false;
1499
+
1500
+		// return the values
1501
+		return array($x, $y);
1502
+	}
1503
+
1504
+	/**
1505
+	 * parse a background repeat
1506
+	 *
1507
+	 * @access public
1508
+	 * @param  string $css
1509
+	 * @return string $value
1510
+	 */
1511
+	public function convertBackgroundRepeat($css)
1512
+	{
1513
+		switch($css)
1514
+		{
1515
+			case 'repeat':
1516
+				return array(true, true);
1517
+			case 'repeat-x':
1518
+				return array(true, false);
1519
+			case 'repeat-y':
1520
+				return array(false, true);
1521
+			case 'no-repeat':
1522
+				return array(false, false);
1523
+		}
1524
+		return null;
1525
+	}
1526
+
1527
+	 /**
1528
+	  * convert a distance to mm
1529
+	  *
1530
+	  * @access public
1531
+	  * @param  string $css distance to convert
1532
+	  * @param  float  $old parent distance
1533
+	  * @return float  $value
1534
+	  */
1535
+	public function convertToMM($css, $old=0.)
1536
+	{
1537
+		$css = trim($css);
1538
+		if (preg_match('/^[0-9\.\-]+$/isU', $css))        $css.= 'px';
1539
+		if (preg_match('/^[0-9\.\-]+px$/isU', $css))      $css = 25.4/96. * str_replace('px', '', $css);
1540
+		else if (preg_match('/^[0-9\.\-]+pt$/isU', $css)) $css = 25.4/72. * str_replace('pt', '', $css);
1541
+		else if (preg_match('/^[0-9\.\-]+in$/isU', $css)) $css = 25.4 * str_replace('in', '', $css);
1542
+		else if (preg_match('/^[0-9\.\-]+mm$/isU', $css)) $css = 1.*str_replace('mm', '', $css);
1543
+		else if (preg_match('/^[0-9\.\-]+%$/isU', $css))  $css = 1.*$old*str_replace('%', '', $css)/100.;
1544
+		else                                              $css = null;
1545
+
1546
+		return $css;
1547
+	}
1548
+
1549
+	/**
1550
+	 * convert a css radius
1551
+	 *
1552
+	 * @access public
1553
+	 * @param  string $css
1554
+	 * @return float  $value
1555
+	 */
1556
+	public function convertToRadius($css)
1557
+	{
1558
+		// explode the value
1559
+		$css = explode(' ', $css);
1560
+
1561
+		foreach ($css as $k => $v) {
1562
+			$v = trim($v);
1563
+			if ($v) {
1564
+				$v = $this->convertToMM($v, 0);
1565
+				if ($v!==null) {
1566
+					$css[$k] = $v;
1567
+				} else {
1568
+					unset($css[$k]);
1569
+				}
1570
+			} else {
1571
+				unset($css[$k]);
1572
+			}
1573
+		}
1574
+
1575
+		return array_values($css);
1576
+	}
1577
+
1578
+	/**
1579
+	 * convert a css color
1580
+	 *
1581
+	 * @access public
1582
+	 * @param  string $css
1583
+	 * @param  &boolean $res
1584
+	 * @return array (r,g, b)
1585
+	 */
1586
+	public function convertToColor($css, &$res)
1587
+	{
1588
+		// prepare the value
1589
+		$css = trim($css);
1590
+		$res = true;
1591
+
1592
+		// if transparent => return null
1593
+		if (strtolower($css)=='transparent') return array(null, null, null);
1594
+
1595
+		// HTML color
1596
+		if (isset($this->_htmlColor[strtolower($css)])) {
1597
+			$css = $this->_htmlColor[strtolower($css)];
1598
+			$r = floatVal(hexdec(substr($css, 0, 2)));
1599
+			$v = floatVal(hexdec(substr($css, 2, 2)));
1600
+			$b = floatVal(hexdec(substr($css, 4, 2)));
1601
+			return array($r, $v, $b);
1602
+		}
1603
+
1604
+		// like #FFFFFF
1605
+		if (preg_match('/^#[0-9A-Fa-f]{6}$/isU', $css)) {
1606
+			$r = floatVal(hexdec(substr($css, 1, 2)));
1607
+			$v = floatVal(hexdec(substr($css, 3, 2)));
1608
+			$b = floatVal(hexdec(substr($css, 5, 2)));
1609
+			return array($r, $v, $b);
1610
+		}
1611
+
1612
+		// like #FFF
1613
+		if (preg_match('/^#[0-9A-F]{3}$/isU', $css)) {
1614
+			$r = floatVal(hexdec(substr($css, 1, 1).substr($css, 1, 1)));
1615
+			$v = floatVal(hexdec(substr($css, 2, 1).substr($css, 2, 1)));
1616
+			$b = floatVal(hexdec(substr($css, 3, 1).substr($css, 3, 1)));
1617
+			return array($r, $v, $b);
1618
+		}
1619
+
1620
+		// like rgb(100, 100, 100)
1621
+		if (preg_match('/rgb\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $css, $match)) {
1622
+			$r = $this->_convertSubColor($match[1]);
1623
+			$v = $this->_convertSubColor($match[2]);
1624
+			$b = $this->_convertSubColor($match[3]);
1625
+			return array($r*255., $v*255., $b*255.);
1626
+		}
1627
+
1628
+		// like cmyk(100, 100, 100, 100)
1629
+		if (preg_match('/cmyk\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $css, $match)) {
1630
+			$c = $this->_convertSubColor($match[1]);
1631
+			$m = $this->_convertSubColor($match[2]);
1632
+			$y = $this->_convertSubColor($match[3]);
1633
+			$k = $this->_convertSubColor($match[4]);
1634
+			return array($c*100., $m*100., $y*100., $k*100.);
1635
+		}
1636
+
1637
+		$res = false;
1638
+		return array(0., 0., 0.);
1639
+	}
1640
+
1641
+	/**
1642
+	 * color value to convert
1643
+	 *
1644
+	 * @access protected
1645
+	 * @param  string $c
1646
+	 * @return float $c 0.->1.
1647
+	 */
1648
+	protected function _convertSubColor($c)
1649
+	{
1650
+		if (substr($c, -1)=='%') {
1651
+			$c = floatVal(substr($c, 0, -1))/100.;
1652
+		} else {
1653
+			$c = floatVal($c);
1654
+			if ($c>1) $c = $c/255.;
1655
+		}
1656
+
1657
+		return $c;
1658
+	}
1659
+
1660
+	/**
1661
+	 * read a css content
1662
+	 *
1663
+	 * @access protected
1664
+	 * @param  &string $code
1665
+	 */
1666
+	protected function _analyseStyle(&$code)
1667
+	{
1668
+		// clean the spaces
1669
+		$code = preg_replace('/[\s]+/', ' ', $code);
1670
+
1671
+		// remove the comments
1672
+		$code = preg_replace('/\/\*.*?\*\//s', '', $code);
1673
+
1674
+		// split each CSS code "selector { value }"
1675
+		preg_match_all('/([^{}]+){([^}]*)}/isU', $code, $match);
1676
+
1677
+		// for each CSS code
1678
+		for ($k=0; $k<count($match[0]); $k++) {
1679
+
1680
+			// selectors
1681
+			$names = strtolower(trim($match[1][$k]));
1682
+
1683
+			// css style
1684
+			$styles = trim($match[2][$k]);
1685
+
1686
+			// explode each value
1687
+			$styles = explode(';', $styles);
1688
+
1689
+			// parse each value
1690
+			$css = array();
1691
+			foreach ($styles as $style) {
1692
+				$tmp = explode(':', $style);
1693
+				if (count($tmp)>1) {
1694
+					$cod = $tmp[0]; unset($tmp[0]); $tmp = implode(':', $tmp);
1695
+					$css[trim(strtolower($cod))] = trim($tmp);
1696
+				}
1697
+			}
1698
+
1699
+			// explode the names
1700
+			$names = explode(',', $names);
1701
+
1702
+			// save the values for each names
1703
+			foreach ($names as $name) {
1704
+				// clean the name
1705
+				$name = trim($name);
1706
+
1707
+				// if a selector with somethink lige :hover => continue
1708
+				if (strpos($name, ':')!==false) continue;
1709
+
1710
+				// save the value
1711
+				if (!isset($this->css[$name]))
1712
+					$this->css[$name] = $css;
1713
+				else
1714
+					$this->css[$name] = array_merge($this->css[$name], $css);
1715
+
1716
+			}
1717
+		}
1718
+
1719
+		// get he list of the keys
1720
+		$this->cssKeys = array_flip(array_keys($this->css));
1721
+	}
1722
+
1723
+	/**
1724
+	 * Extract the css files from a html code
1725
+	 *
1726
+	 * @access public
1727
+	 * @param  string   &$html
1728
+	 */
1729
+	public function readStyle(&$html)
1730
+	{
1731
+		// the CSS content
1732
+		$style = ' ';
1733
+
1734
+		// extract the link tags, and remove them in the html code
1735
+		preg_match_all('/<link([^>]*)>/isU', $html, $match);
1736
+		$html = preg_replace('/<link[^>]*>/isU', '', $html);
1737
+		$html = preg_replace('/<\/link[^>]*>/isU', '', $html);
1738
+
1739
+		// analyse each link tag
1740
+		foreach ($match[1] as $code) {
1741
+			$tmp = array();
1742
+
1743
+			// read the attributes name=value
1744
+			$prop = '([a-zA-Z0-9_]+)=([^"\'\s>]+)';
1745
+			preg_match_all('/'.$prop.'/is', $code, $match);
1746
+			for ($k=0; $k<count($match[0]); $k++) {
1747
+				$tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1748
+			}
1749
+
1750
+			// read the attributes name="value"
1751
+			$prop = '([a-zA-Z0-9_]+)=["]([^"]*)["]';
1752
+			preg_match_all('/'.$prop.'/is', $code, $match);
1753
+			for ($k=0; $k<count($match[0]); $k++) {
1754
+				$tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1755
+			}
1756
+
1757
+			// read the attributes name='value'
1758
+			$prop = "([a-zA-Z0-9_]+)=[']([^']*)[']";
1759
+			preg_match_all('/'.$prop.'/is', $code, $match);
1760
+			for ($k=0; $k<count($match[0]); $k++) {
1761
+				$tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1762
+			}
1763
+
1764
+			// if type text/css => we keep it
1765
+			if (isset($tmp['type']) && strtolower($tmp['type'])=='text/css' && isset($tmp['href'])) {
1766
+
1767
+				// get the href
1768
+				$url = $tmp['href'];
1769
+
1770
+				// get the content of the css file
1771
+				$content = @file_get_contents($url);
1772
+
1773
+				// if "http://" in the url
1774
+				if (strpos($url, 'http://')!==false) {
1775
+
1776
+					// get the domain "http://xxx/"
1777
+					$url = str_replace('http://', '', $url);
1778
+					$url = explode('/', $url);
1779
+					$urlMain = 'http://'.$url[0].'/';
1780
+
1781
+					// get the absolute url of the path
1782
+					$urlSelf = $url; unset($urlSelf[count($urlSelf)-1]); $urlSelf = 'http://'.implode('/', $urlSelf).'/';
1783
+
1784
+					// adapt the url in the css content
1785
+					$content = preg_replace('/url\(([^\\\\][^)]*)\)/isU', 'url('.$urlSelf.'$1)', $content);
1786
+					$content = preg_replace('/url\((\\\\[^)]*)\)/isU', 'url('.$urlMain.'$1)', $content);
1787
+				} else {
1788 1788
 // @TODO correction on url in absolute on a local css content
1789
-                    // $content = preg_replace('/url\(([^)]*)\)/isU', 'url('.dirname($url).'/$1)', $content);
1790
-                }
1791
-
1792
-                // add to the CSS content
1793
-                $style.= $content."\n";
1794
-            }
1795
-        }
1796
-
1797
-        // extract the style tags des tags style, and remove them in the html code
1798
-        preg_match_all('/<style[^>]*>(.*)<\/style[^>]*>/isU', $html, $match);
1799
-        $html = preg_replace('/<style[^>]*>(.*)<\/style[^>]*>/isU', '', $html);
1800
-
1801
-        // analyse each style tags
1802
-        foreach ($match[1] as $code) {
1803
-            // add to the CSS content
1804
-            $code = str_replace('<!--', '', $code);
1805
-            $code = str_replace('-->', '', $code);
1806
-            $style.= $code."\n";
1807
-        }
1808
-
1809
-        //analyse the css content
1810
-        $this->_analyseStyle($style);
1811
-    }
1789
+					// $content = preg_replace('/url\(([^)]*)\)/isU', 'url('.dirname($url).'/$1)', $content);
1790
+				}
1791
+
1792
+				// add to the CSS content
1793
+				$style.= $content."\n";
1794
+			}
1795
+		}
1796
+
1797
+		// extract the style tags des tags style, and remove them in the html code
1798
+		preg_match_all('/<style[^>]*>(.*)<\/style[^>]*>/isU', $html, $match);
1799
+		$html = preg_replace('/<style[^>]*>(.*)<\/style[^>]*>/isU', '', $html);
1800
+
1801
+		// analyse each style tags
1802
+		foreach ($match[1] as $code) {
1803
+			// add to the CSS content
1804
+			$code = str_replace('<!--', '', $code);
1805
+			$code = str_replace('-->', '', $code);
1806
+			$style.= $code."\n";
1807
+		}
1808
+
1809
+		//analyse the css content
1810
+		$this->_analyseStyle($style);
1811
+	}
1812 1812
 }
1813 1813
\ No newline at end of file
Please login to merge, or discard this patch.
web_interface/astpp/application/libraries/html2pdf/html2pdf.php 1 patch
Indentation   +6465 added lines, -6466 removed lines patch added patch discarded remove patch
@@ -11,485 +11,484 @@  discard block
 block discarded – undo
11 11
 
12 12
 if (!defined('__CLASS_HTML2PDF__')) {
13 13
 
14
-    define('__CLASS_HTML2PDF__', '4.03');
15
-    define('HTML2PDF_USED_TCPDF_VERSION', '5.0.002');
16
-
17
-    require_once('_class/exception.class.php');
18
-    require_once('_class/locale.class.php');
19
-    require_once('_class/myPdf.class.php');
20
-    require_once('_class/parsingHtml.class.php');
21
-    require_once('_class/parsingCss.class.php');
22
-
23
-    class HTML2PDF
24
-    {
25
-        /**
26
-         * HTML2PDF_myPdf object, extends from TCPDF
27
-         * @var HTML2PDF_myPdf
28
-         */
29
-        public $pdf = null;
30
-
31
-        /**
32
-         * CSS parsing
33
-         * @var HTML2PDF_parsingCss
34
-         */
35
-        public $parsingCss = null;
36
-
37
-        /**
38
-         * HTML parsing
39
-         * @var HTML2PDF_parsingHtml
40
-         */
41
-        public $parsingHtml = null;
42
-
43
-        protected $_langue           = 'fr';        // locale of the messages
44
-        protected $_orientation      = 'P';         // page orientation : Portrait ou Landscape
45
-        protected $_format           = 'A4';        // page format : A4, A3, ...
46
-        protected $_encoding         = '';          // charset encoding
47
-        protected $_unicode          = true;        // means that the input text is unicode (default = true)
48
-
49
-        protected $_testTdInOnepage  = true;        // test of TD that can not take more than one page
50
-        protected $_testIsImage      = true;        // test if the images exist or not
51
-        protected $_testIsDeprecated = false;       // test the deprecated functions
52
-
53
-        protected $_parsePos         = 0;           // position in the parsing
54
-        protected $_tempPos          = 0;           // temporary position for complex table
55
-        protected $_page             = 0;           // current page number
56
-
57
-        protected $_subHtml          = null;        // sub html
58
-        protected $_subPart          = false;       // sub HTML2PDF
59
-        protected $_subHEADER        = array();     // sub action to make the header
60
-        protected $_subFOOTER        = array();     // sub action to make the footer
61
-        protected $_subSTATES        = array();     // array to save some parameters
62
-
63
-        protected $_isSubPart        = false;       // flag : in a sub html2pdf
64
-        protected $_isInThead        = false;       // flag : in a thead
65
-        protected $_isInTfoot        = false;       // flag : in a tfoot
66
-        protected $_isInOverflow     = false;       // flag : in a overflow
67
-        protected $_isInFooter       = false;       // flag : in a footer
68
-        protected $_isInDraw         = null;        // flag : in a draw (svg)
69
-        protected $_isAfterFloat     = false;       // flag : is just after a float
70
-        protected $_isInForm         = false;       // flag : is in a float. false / action of the form
71
-        protected $_isInLink         = '';          // flag : is in a link. empty / href of the link
72
-        protected $_isInParagraph    = false;       // flag : is in a paragraph
73
-        protected $_isForOneLine     = false;       // flag : in a specific sub html2pdf to have the height of the next line
74
-
75
-        protected $_maxX             = 0;           // maximum X of the current zone
76
-        protected $_maxY             = 0;           // maximum Y of the current zone
77
-        protected $_maxE             = 0;           // number of elements in the current zone
78
-        protected $_maxH             = 0;           // maximum height of the line in the current zone
79
-        protected $_maxSave          = array();     // save the maximums of the current zone
80
-        protected $_currentH         = 0;           // height of the current line
81
-
82
-        protected $_defaultLeft      = 0;           // default marges of the page
83
-        protected $_defaultTop       = 0;
84
-        protected $_defaultRight     = 0;
85
-        protected $_defaultBottom    = 0;
86
-        protected $_defaultFont      = null;        // default font to use, is the asked font does not exist
87
-
88
-        protected $_margeLeft        = 0;           // current marges of the page
89
-        protected $_margeTop         = 0;
90
-        protected $_margeRight       = 0;
91
-        protected $_margeBottom      = 0;
92
-        protected $_marges           = array();     // save the different marges of the current page
93
-        protected $_pageMarges       = array();     // float marges of the current page
94
-        protected $_background       = array();     // background informations
95
-
96
-
97
-        protected $_firstPage        = true;        // flag : first page
98
-        protected $_defList          = array();     // table to save the stats of the tags UL and OL
99
-
100
-        protected $_lstAnchor        = array();     // list of the anchors
101
-        protected $_lstField         = array();     // list of the fields
102
-        protected $_lstSelect        = array();     // list of the options of the current select
103
-        protected $_previousCall     = null;        // last action called
104
-
105
-        protected $_debugActif       = false;       // flag : mode debug is active
106
-        protected $_debugOkUsage     = false;       // flag : the function memory_get_usage exist
107
-        protected $_debugOkPeak      = false;       // flag : the function memory_get_peak_usage exist
108
-        protected $_debugLevel       = 0;           // level in the debug
109
-        protected $_debugStartTime   = 0;           // debug start time
110
-        protected $_debugLastTime    = 0;           // debug stop time
111
-
112
-        static protected $_subobj    = null;        // object html2pdf prepared in order to accelerate the creation of sub html2pdf
113
-        static protected $_tables    = array();     // static table to prepare the nested html tables
114
-
115
-        /**
116
-         * class constructor
117
-         *
118
-         * @access public
119
-         * @param  string   $orientation page orientation, same as TCPDF
120
-         * @param  mixed    $format      The format used for pages, same as TCPDF
121
-         * @param  $tring   $langue      Langue : fr, en, it...
122
-         * @param  boolean  $unicode     TRUE means that the input text is unicode (default = true)
123
-         * @param  String   $encoding    charset encoding; default is UTF-8
124
-         * @param  array    $marges      Default marges (left, top, right, bottom)
125
-         * @return HTML2PDF $this
126
-         */
127
-        public function __construct($orientation = 'P', $format = 'A4', $langue='en', $unicode=true, $encoding='UTF-8', $marges = array(5, 5, 5, 8))
128
-        {
129
-            // init the page number
130
-            $this->_page         = 0;
131
-            $this->_firstPage    = true;
132
-
133
-            // save the parameters
134
-            $this->_orientation  = $orientation;
135
-            $this->_format       = $format;
136
-            $this->_langue       = strtolower($langue);
137
-            $this->_unicode      = $unicode;
138
-            $this->_encoding     = $encoding;
139
-
140
-            // load the Local
141
-            HTML2PDF_locale::load($this->_langue);
142
-
143
-            // create the  HTML2PDF_myPdf object
144
-            $this->pdf = new HTML2PDF_myPdf($orientation, 'mm', $format, $unicode, $encoding);
145
-
146
-            // init the CSS parsing object
147
-            $this->parsingCss = new HTML2PDF_parsingCss($this->pdf);
148
-            $this->parsingCss->fontSet();
149
-            $this->_defList = array();
150
-
151
-            // init some tests
152
-            $this->setTestTdInOnePage(true);
153
-            $this->setTestIsImage(true);
154
-            $this->setTestIsDeprecated(true);
155
-
156
-            // init the default font
157
-            $this->setDefaultFont(null);
158
-
159
-            // init the HTML parsing object
160
-            $this->parsingHtml = new HTML2PDF_parsingHtml($this->_encoding);
161
-            $this->_subHtml = null;
162
-            $this->_subPart = false;
163
-
164
-            // init the marges of the page
165
-            if (!is_array($marges)) $marges = array($marges, $marges, $marges, $marges);
166
-            $this->_setDefaultMargins($marges[0], $marges[1], $marges[2], $marges[3]);
167
-            $this->_setMargins();
168
-            $this->_marges = array();
169
-
170
-            // init the form's fields
171
-            $this->_lstField = array();
172
-
173
-            return $this;
174
-        }
175
-
176
-        /**
177
-         * Destructor
178
-         *
179
-         * @access public
180
-         * @return null
181
-         */
182
-        public function __destruct()
183
-        {
184
-
185
-        }
186
-
187
-        /**
188
-         * Clone to create a sub HTML2PDF from HTML2PDF::$_subobj
189
-         *
190
-         * @access public
191
-         */
192
-        public function __clone()
193
-        {
194
-            $this->pdf = clone $this->pdf;
195
-            $this->parsingHtml = clone $this->parsingHtml;
196
-            $this->parsingCss = clone $this->parsingCss;
197
-            $this->parsingCss->setPdfParent($this->pdf);
198
-        }
199
-
200
-        /**
201
-         * set the debug mode to On
202
-         *
203
-         * @access public
204
-         * @return HTML2PDF $this
205
-         */
206
-        public function setModeDebug()
207
-        {
208
-            $time = microtime(true);
209
-
210
-            $this->_debugActif     = true;
211
-            $this->_debugOkUsage   = function_exists('memory_get_usage');
212
-            $this->_debugOkPeak    = function_exists('memory_get_peak_usage');
213
-            $this->_debugStartTime = $time;
214
-            $this->_debugLastTime  = $time;
215
-
216
-            $this->_DEBUG_stepline('step', 'time', 'delta', 'memory', 'peak');
217
-            $this->_DEBUG_add('Init debug');
218
-
219
-            return $this;
220
-        }
221
-
222
-        /**
223
-         * Set the test of TD thdat can not take more than one page
224
-         *
225
-         * @access public
226
-         * @param  boolean  $mode
227
-         * @return HTML2PDF $this
228
-         */
229
-        public function setTestTdInOnePage($mode = true)
230
-        {
231
-            $this->_testTdInOnepage = $mode ? true : false;
232
-
233
-            return $this;
234
-        }
235
-
236
-        /**
237
-         * Set the test if the images exist or not
238
-         *
239
-         * @access public
240
-         * @param  boolean  $mode
241
-         * @return HTML2PDF $this
242
-         */
243
-        public function setTestIsImage($mode = true)
244
-        {
245
-            $this->_testIsImage = $mode ? true : false;
246
-
247
-            return $this;
248
-        }
249
-
250
-        /**
251
-         * Set the test on deprecated functions
252
-         *
253
-         * @access public
254
-         * @param  boolean  $mode
255
-         * @return HTML2PDF $this
256
-         */
257
-        public function setTestIsDeprecated($mode = true)
258
-        {
259
-            $this->_testIsDeprecated = $mode ? true : false;
260
-
261
-            return $this;
262
-        }
263
-
264
-        /**
265
-         * Set the default font to use, if no font is specify, or if the asked font does not exist
266
-         *
267
-         * @access public
268
-         * @param  string   $default name of the default font to use. If null : Arial is no font is specify, and error if the asked font does not exist
269
-         * @return HTML2PDF $this
270
-         */
271
-        public function setDefaultFont($default = null)
272
-        {
273
-            $this->_defaultFont = $default;
274
-            $this->parsingCss->setDefaultFont($default);
275
-
276
-            return $this;
277
-        }
278
-
279
-        /**
280
-         * add a font, see TCPDF function addFont
281
-         *
282
-         * @access public
283
-         * @param string $family Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font.
284
-         * @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>
285
-         * @param string $fontfile The font definition file. By default, the name is built from the family and style, in lower case with no spaces.
286
-         * @return HTML2PDF $this
287
-         * @see TCPDF::addFont
288
-         */
289
-        public function addFont($family, $style='', $file='')
290
-        {
291
-            $this->pdf->AddFont($family, $style, $file);
292
-
293
-            return $this;
294
-        }
295
-
296
-        /**
297
-         * display a automatic index, from the bookmarks
298
-         *
299
-         * @access public
300
-         * @param  string  $titre         index title
301
-         * @param  int     $sizeTitle     font size of the index title, in mm
302
-         * @param  int     $sizeBookmark  font size of the index, in mm
303
-         * @param  boolean $bookmarkTitle add a bookmark for the index, at his beginning
304
-         * @param  boolean $displayPage   display the page numbers
305
-         * @param  int     $onPage        if null : at the end of the document on a new page, else on the $onPage page
306
-         * @param  string  $fontName      font name to use
307
-         * @return null
308
-         */
309
-        public function createIndex($titre = 'Index', $sizeTitle = 20, $sizeBookmark = 15, $bookmarkTitle = true, $displayPage = true, $onPage = null, $fontName = 'helvetica')
310
-        {
311
-            $oldPage = $this->_INDEX_NewPage($onPage);
312
-            $this->pdf->createIndex($this, $titre, $sizeTitle, $sizeBookmark, $bookmarkTitle, $displayPage, $onPage, $fontName);
313
-            if ($oldPage) $this->pdf->setPage($oldPage);
314
-        }
315
-
316
-        /**
317
-         * clean up the objects
318
-         *
319
-         * @access protected
320
-         */
321
-        protected function _cleanUp()
322
-        {
323
-            HTML2PDF::$_subobj = null;
324
-            HTML2PDF::$_tables = array();
325
-        }
326
-
327
-        /**
328
-         * Send the document to a given destination: string, local file or browser.
329
-         * Dest can be :
330
-         *  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.
331
-         *  D : send to the browser and force a file download with the name given by name.
332
-         *  F : save to a local server file with the name given by name.
333
-         *  S : return the document as a string. name is ignored.
334
-         *  FI: equivalent to F + I option
335
-         *  FD: equivalent to F + D option
336
-         *  true  => I
337
-         *  false => S
338
-         *
339
-         * @param  string $name The name of the file when saved.
340
-         * @param  string $dest Destination where to send the document.
341
-         * @return string content of the PDF, if $dest=S
342
-         * @see TCPDF::close
343
-         * @access public
344
-
345
-         */
346
-        public function Output($name = '', $dest = false)
347
-        {
348
-            // close the pdf and clean up
349
-            $this->_cleanUp();
350
-
351
-            // if on debug mode
352
-            if ($this->_debugActif) {
353
-                $this->_DEBUG_add('Before output');
354
-                $this->pdf->Close();
355
-                exit;
356
-            }
357
-
358
-            // complete parameters
359
-            if ($dest===false) $dest = 'I';
360
-            if ($dest===true)  $dest = 'S';
361
-            if ($dest==='')    $dest = 'I';
362
-            if ($name=='')     $name='document.pdf';
363
-
364
-            // clean up the destination
365
-            $dest = strtoupper($dest);
366
-            if (!in_array($dest, array('I', 'D', 'F', 'S', 'FI','FD'))) $dest = 'I';
367
-
368
-            // the name must be a PDF name
369
-            if (strtolower(substr($name, -4))!='.pdf') {
370
-                throw new HTML2PDF_exception(0, 'The output document name "'.$name.'" is not a PDF name');
371
-            }
372
-
373
-            // call the output of TCPDF
374
-            return $this->pdf->Output($name, $dest);
375
-        }
376
-
377
-        /**
378
-         * convert HTML to PDF
379
-         *
380
-         * @access public
381
-         * @param  string   $html
382
-         * @param  boolean  $debugVue  enable the HTML debug vue
383
-         * @return null
384
-         */
385
-        public function writeHTML($html, $debugVue = false)
386
-        {
387
-            // if it is a real html page, we have to convert it
388
-            if (preg_match('/<body/isU', $html))
389
-                $html = $this->getHtmlFromPage($html);
390
-
391
-            $html = str_replace('[[date_y]]', date('Y'), $html);
392
-            $html = str_replace('[[date_m]]', date('m'), $html);
393
-            $html = str_replace('[[date_d]]', date('d'), $html);
394
-
395
-            $html = str_replace('[[date_h]]', date('H'), $html);
396
-            $html = str_replace('[[date_i]]', date('i'), $html);
397
-            $html = str_replace('[[date_s]]', date('s'), $html);
398
-
399
-            // If we are in HTML debug vue : display the HTML
400
-            if ($debugVue) {
401
-                return $this->_vueHTML($html);
402
-            }
403
-
404
-            // convert HTMl to PDF
405
-            $this->parsingCss->readStyle($html);
406
-            $this->parsingHtml->setHTML($html);
407
-            $this->parsingHtml->parse();
408
-            $this->_makeHTMLcode();
409
-        }
410
-
411
-        /**
412
-         * convert the HTML of a real page, to a code adapted to HTML2PDF
413
-         *
414
-         * @access public
415
-         * @param  string HTML of a real page
416
-         * @return string HTML adapted to HTML2PDF
417
-         */
418
-        public function getHtmlFromPage($html)
419
-        {
420
-            $html = str_replace('<BODY', '<body', $html);
421
-            $html = str_replace('</BODY', '</body', $html);
422
-
423
-            // extract the content
424
-            $res = explode('<body', $html);
425
-            if (count($res)<2) return $html;
426
-            $content = '<page'.$res[1];
427
-            $content = explode('</body', $content);
428
-            $content = $content[0].'</page>';
429
-
430
-            // extract the link tags
431
-            preg_match_all('/<link([^>]*)>/isU', $html, $match);
432
-            foreach ($match[0] as $src)
433
-                $content = $src.'</link>'.$content;
434
-
435
-            // extract the css style tags
436
-            preg_match_all('/<style[^>]*>(.*)<\/style[^>]*>/isU', $html, $match);
437
-            foreach ($match[0] as $src)
438
-                $content = $src.$content;
439
-
440
-            return $content;
441
-        }
442
-
443
-        /**
444
-         * init a sub HTML2PDF. does not use it directly. Only the method createSubHTML must use it
445
-         *
446
-         * @access public
447
-         * @param  string  $format
448
-         * @param  string  $orientation
449
-         * @param  array   $marge
450
-         * @param  integer $page
451
-         * @param  array   $defLIST
452
-         * @param  integer $myLastPageGroup
453
-         * @param  integer $myLastPageGroupNb
454
-         */
455
-        public function initSubHtml($format, $orientation, $marge, $page, $defLIST, $myLastPageGroup, $myLastPageGroupNb)
456
-        {
457
-            $this->_isSubPart = true;
458
-
459
-            $this->parsingCss->setOnlyLeft();
460
-
461
-            $this->_setNewPage($format, $orientation, null, null, ($myLastPageGroup!==null));
462
-
463
-            $this->_saveMargin(0, 0, $marge);
464
-            $this->_defList = $defLIST;
465
-
466
-            $this->_page = $page;
467
-            $this->pdf->setMyLastPageGroup($myLastPageGroup);
468
-            $this->pdf->setMyLastPageGroupNb($myLastPageGroupNb);
469
-            $this->pdf->setXY(0, 0);
470
-            $this->parsingCss->fontSet();
471
-        }
472
-
473
-        /**
474
-         * display the content in HTML moden for debug
475
-         *
476
-         * @access protected
477
-         * @param  string $contenu
478
-         */
479
-        protected function _vueHTML($content)
480
-        {
481
-            $content = preg_replace('/<page_header([^>]*)>/isU', '<hr>'.HTML2PDF_locale::get('vue01').' : $1<hr><div$1>', $content);
482
-            $content = preg_replace('/<page_footer([^>]*)>/isU', '<hr>'.HTML2PDF_locale::get('vue02').' : $1<hr><div$1>', $content);
483
-            $content = preg_replace('/<page([^>]*)>/isU', '<hr>'.HTML2PDF_locale::get('vue03').' : $1<hr><div$1>', $content);
484
-            $content = preg_replace('/<\/page([^>]*)>/isU', '</div><hr>', $content);
485
-            $content = preg_replace('/<bookmark([^>]*)>/isU', '<hr>bookmark : $1<hr>', $content);
486
-            $content = preg_replace('/<\/bookmark([^>]*)>/isU', '', $content);
487
-            $content = preg_replace('/<barcode([^>]*)>/isU', '<hr>barcode : $1<hr>', $content);
488
-            $content = preg_replace('/<\/barcode([^>]*)>/isU', '', $content);
489
-            $content = preg_replace('/<qrcode([^>]*)>/isU', '<hr>qrcode : $1<hr>', $content);
490
-            $content = preg_replace('/<\/qrcode([^>]*)>/isU', '', $content);
491
-
492
-            echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
14
+	define('__CLASS_HTML2PDF__', '4.03');
15
+	define('HTML2PDF_USED_TCPDF_VERSION', '5.0.002');
16
+
17
+	require_once('_class/exception.class.php');
18
+	require_once('_class/locale.class.php');
19
+	require_once('_class/myPdf.class.php');
20
+	require_once('_class/parsingHtml.class.php');
21
+	require_once('_class/parsingCss.class.php');
22
+
23
+	class HTML2PDF
24
+	{
25
+		/**
26
+		 * HTML2PDF_myPdf object, extends from TCPDF
27
+		 * @var HTML2PDF_myPdf
28
+		 */
29
+		public $pdf = null;
30
+
31
+		/**
32
+		 * CSS parsing
33
+		 * @var HTML2PDF_parsingCss
34
+		 */
35
+		public $parsingCss = null;
36
+
37
+		/**
38
+		 * HTML parsing
39
+		 * @var HTML2PDF_parsingHtml
40
+		 */
41
+		public $parsingHtml = null;
42
+
43
+		protected $_langue           = 'fr';        // locale of the messages
44
+		protected $_orientation      = 'P';         // page orientation : Portrait ou Landscape
45
+		protected $_format           = 'A4';        // page format : A4, A3, ...
46
+		protected $_encoding         = '';          // charset encoding
47
+		protected $_unicode          = true;        // means that the input text is unicode (default = true)
48
+
49
+		protected $_testTdInOnepage  = true;        // test of TD that can not take more than one page
50
+		protected $_testIsImage      = true;        // test if the images exist or not
51
+		protected $_testIsDeprecated = false;       // test the deprecated functions
52
+
53
+		protected $_parsePos         = 0;           // position in the parsing
54
+		protected $_tempPos          = 0;           // temporary position for complex table
55
+		protected $_page             = 0;           // current page number
56
+
57
+		protected $_subHtml          = null;        // sub html
58
+		protected $_subPart          = false;       // sub HTML2PDF
59
+		protected $_subHEADER        = array();     // sub action to make the header
60
+		protected $_subFOOTER        = array();     // sub action to make the footer
61
+		protected $_subSTATES        = array();     // array to save some parameters
62
+
63
+		protected $_isSubPart        = false;       // flag : in a sub html2pdf
64
+		protected $_isInThead        = false;       // flag : in a thead
65
+		protected $_isInTfoot        = false;       // flag : in a tfoot
66
+		protected $_isInOverflow     = false;       // flag : in a overflow
67
+		protected $_isInFooter       = false;       // flag : in a footer
68
+		protected $_isInDraw         = null;        // flag : in a draw (svg)
69
+		protected $_isAfterFloat     = false;       // flag : is just after a float
70
+		protected $_isInForm         = false;       // flag : is in a float. false / action of the form
71
+		protected $_isInLink         = '';          // flag : is in a link. empty / href of the link
72
+		protected $_isInParagraph    = false;       // flag : is in a paragraph
73
+		protected $_isForOneLine     = false;       // flag : in a specific sub html2pdf to have the height of the next line
74
+
75
+		protected $_maxX             = 0;           // maximum X of the current zone
76
+		protected $_maxY             = 0;           // maximum Y of the current zone
77
+		protected $_maxE             = 0;           // number of elements in the current zone
78
+		protected $_maxH             = 0;           // maximum height of the line in the current zone
79
+		protected $_maxSave          = array();     // save the maximums of the current zone
80
+		protected $_currentH         = 0;           // height of the current line
81
+
82
+		protected $_defaultLeft      = 0;           // default marges of the page
83
+		protected $_defaultTop       = 0;
84
+		protected $_defaultRight     = 0;
85
+		protected $_defaultBottom    = 0;
86
+		protected $_defaultFont      = null;        // default font to use, is the asked font does not exist
87
+
88
+		protected $_margeLeft        = 0;           // current marges of the page
89
+		protected $_margeTop         = 0;
90
+		protected $_margeRight       = 0;
91
+		protected $_margeBottom      = 0;
92
+		protected $_marges           = array();     // save the different marges of the current page
93
+		protected $_pageMarges       = array();     // float marges of the current page
94
+		protected $_background       = array();     // background informations
95
+
96
+
97
+		protected $_firstPage        = true;        // flag : first page
98
+		protected $_defList          = array();     // table to save the stats of the tags UL and OL
99
+
100
+		protected $_lstAnchor        = array();     // list of the anchors
101
+		protected $_lstField         = array();     // list of the fields
102
+		protected $_lstSelect        = array();     // list of the options of the current select
103
+		protected $_previousCall     = null;        // last action called
104
+
105
+		protected $_debugActif       = false;       // flag : mode debug is active
106
+		protected $_debugOkUsage     = false;       // flag : the function memory_get_usage exist
107
+		protected $_debugOkPeak      = false;       // flag : the function memory_get_peak_usage exist
108
+		protected $_debugLevel       = 0;           // level in the debug
109
+		protected $_debugStartTime   = 0;           // debug start time
110
+		protected $_debugLastTime    = 0;           // debug stop time
111
+
112
+		static protected $_subobj    = null;        // object html2pdf prepared in order to accelerate the creation of sub html2pdf
113
+		static protected $_tables    = array();     // static table to prepare the nested html tables
114
+
115
+		/**
116
+		 * class constructor
117
+		 *
118
+		 * @access public
119
+		 * @param  string   $orientation page orientation, same as TCPDF
120
+		 * @param  mixed    $format      The format used for pages, same as TCPDF
121
+		 * @param  $tring   $langue      Langue : fr, en, it...
122
+		 * @param  boolean  $unicode     TRUE means that the input text is unicode (default = true)
123
+		 * @param  String   $encoding    charset encoding; default is UTF-8
124
+		 * @param  array    $marges      Default marges (left, top, right, bottom)
125
+		 * @return HTML2PDF $this
126
+		 */
127
+		public function __construct($orientation = 'P', $format = 'A4', $langue='en', $unicode=true, $encoding='UTF-8', $marges = array(5, 5, 5, 8))
128
+		{
129
+			// init the page number
130
+			$this->_page         = 0;
131
+			$this->_firstPage    = true;
132
+
133
+			// save the parameters
134
+			$this->_orientation  = $orientation;
135
+			$this->_format       = $format;
136
+			$this->_langue       = strtolower($langue);
137
+			$this->_unicode      = $unicode;
138
+			$this->_encoding     = $encoding;
139
+
140
+			// load the Local
141
+			HTML2PDF_locale::load($this->_langue);
142
+
143
+			// create the  HTML2PDF_myPdf object
144
+			$this->pdf = new HTML2PDF_myPdf($orientation, 'mm', $format, $unicode, $encoding);
145
+
146
+			// init the CSS parsing object
147
+			$this->parsingCss = new HTML2PDF_parsingCss($this->pdf);
148
+			$this->parsingCss->fontSet();
149
+			$this->_defList = array();
150
+
151
+			// init some tests
152
+			$this->setTestTdInOnePage(true);
153
+			$this->setTestIsImage(true);
154
+			$this->setTestIsDeprecated(true);
155
+
156
+			// init the default font
157
+			$this->setDefaultFont(null);
158
+
159
+			// init the HTML parsing object
160
+			$this->parsingHtml = new HTML2PDF_parsingHtml($this->_encoding);
161
+			$this->_subHtml = null;
162
+			$this->_subPart = false;
163
+
164
+			// init the marges of the page
165
+			if (!is_array($marges)) $marges = array($marges, $marges, $marges, $marges);
166
+			$this->_setDefaultMargins($marges[0], $marges[1], $marges[2], $marges[3]);
167
+			$this->_setMargins();
168
+			$this->_marges = array();
169
+
170
+			// init the form's fields
171
+			$this->_lstField = array();
172
+
173
+			return $this;
174
+		}
175
+
176
+		/**
177
+		 * Destructor
178
+		 *
179
+		 * @access public
180
+		 * @return null
181
+		 */
182
+		public function __destruct()
183
+		{
184
+
185
+		}
186
+
187
+		/**
188
+		 * Clone to create a sub HTML2PDF from HTML2PDF::$_subobj
189
+		 *
190
+		 * @access public
191
+		 */
192
+		public function __clone()
193
+		{
194
+			$this->pdf = clone $this->pdf;
195
+			$this->parsingHtml = clone $this->parsingHtml;
196
+			$this->parsingCss = clone $this->parsingCss;
197
+			$this->parsingCss->setPdfParent($this->pdf);
198
+		}
199
+
200
+		/**
201
+		 * set the debug mode to On
202
+		 *
203
+		 * @access public
204
+		 * @return HTML2PDF $this
205
+		 */
206
+		public function setModeDebug()
207
+		{
208
+			$time = microtime(true);
209
+
210
+			$this->_debugActif     = true;
211
+			$this->_debugOkUsage   = function_exists('memory_get_usage');
212
+			$this->_debugOkPeak    = function_exists('memory_get_peak_usage');
213
+			$this->_debugStartTime = $time;
214
+			$this->_debugLastTime  = $time;
215
+
216
+			$this->_DEBUG_stepline('step', 'time', 'delta', 'memory', 'peak');
217
+			$this->_DEBUG_add('Init debug');
218
+
219
+			return $this;
220
+		}
221
+
222
+		/**
223
+		 * Set the test of TD thdat can not take more than one page
224
+		 *
225
+		 * @access public
226
+		 * @param  boolean  $mode
227
+		 * @return HTML2PDF $this
228
+		 */
229
+		public function setTestTdInOnePage($mode = true)
230
+		{
231
+			$this->_testTdInOnepage = $mode ? true : false;
232
+
233
+			return $this;
234
+		}
235
+
236
+		/**
237
+		 * Set the test if the images exist or not
238
+		 *
239
+		 * @access public
240
+		 * @param  boolean  $mode
241
+		 * @return HTML2PDF $this
242
+		 */
243
+		public function setTestIsImage($mode = true)
244
+		{
245
+			$this->_testIsImage = $mode ? true : false;
246
+
247
+			return $this;
248
+		}
249
+
250
+		/**
251
+		 * Set the test on deprecated functions
252
+		 *
253
+		 * @access public
254
+		 * @param  boolean  $mode
255
+		 * @return HTML2PDF $this
256
+		 */
257
+		public function setTestIsDeprecated($mode = true)
258
+		{
259
+			$this->_testIsDeprecated = $mode ? true : false;
260
+
261
+			return $this;
262
+		}
263
+
264
+		/**
265
+		 * Set the default font to use, if no font is specify, or if the asked font does not exist
266
+		 *
267
+		 * @access public
268
+		 * @param  string   $default name of the default font to use. If null : Arial is no font is specify, and error if the asked font does not exist
269
+		 * @return HTML2PDF $this
270
+		 */
271
+		public function setDefaultFont($default = null)
272
+		{
273
+			$this->_defaultFont = $default;
274
+			$this->parsingCss->setDefaultFont($default);
275
+
276
+			return $this;
277
+		}
278
+
279
+		/**
280
+		 * add a font, see TCPDF function addFont
281
+		 *
282
+		 * @access public
283
+		 * @param string $family Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font.
284
+		 * @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>
285
+		 * @param string $fontfile The font definition file. By default, the name is built from the family and style, in lower case with no spaces.
286
+		 * @return HTML2PDF $this
287
+		 * @see TCPDF::addFont
288
+		 */
289
+		public function addFont($family, $style='', $file='')
290
+		{
291
+			$this->pdf->AddFont($family, $style, $file);
292
+
293
+			return $this;
294
+		}
295
+
296
+		/**
297
+		 * display a automatic index, from the bookmarks
298
+		 *
299
+		 * @access public
300
+		 * @param  string  $titre         index title
301
+		 * @param  int     $sizeTitle     font size of the index title, in mm
302
+		 * @param  int     $sizeBookmark  font size of the index, in mm
303
+		 * @param  boolean $bookmarkTitle add a bookmark for the index, at his beginning
304
+		 * @param  boolean $displayPage   display the page numbers
305
+		 * @param  int     $onPage        if null : at the end of the document on a new page, else on the $onPage page
306
+		 * @param  string  $fontName      font name to use
307
+		 * @return null
308
+		 */
309
+		public function createIndex($titre = 'Index', $sizeTitle = 20, $sizeBookmark = 15, $bookmarkTitle = true, $displayPage = true, $onPage = null, $fontName = 'helvetica')
310
+		{
311
+			$oldPage = $this->_INDEX_NewPage($onPage);
312
+			$this->pdf->createIndex($this, $titre, $sizeTitle, $sizeBookmark, $bookmarkTitle, $displayPage, $onPage, $fontName);
313
+			if ($oldPage) $this->pdf->setPage($oldPage);
314
+		}
315
+
316
+		/**
317
+		 * clean up the objects
318
+		 *
319
+		 * @access protected
320
+		 */
321
+		protected function _cleanUp()
322
+		{
323
+			HTML2PDF::$_subobj = null;
324
+			HTML2PDF::$_tables = array();
325
+		}
326
+
327
+		/**
328
+		 * Send the document to a given destination: string, local file or browser.
329
+		 * Dest can be :
330
+		 *  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.
331
+		 *  D : send to the browser and force a file download with the name given by name.
332
+		 *  F : save to a local server file with the name given by name.
333
+		 *  S : return the document as a string. name is ignored.
334
+		 *  FI: equivalent to F + I option
335
+		 *  FD: equivalent to F + D option
336
+		 *  true  => I
337
+		 *  false => S
338
+		 *
339
+		 * @param  string $name The name of the file when saved.
340
+		 * @param  string $dest Destination where to send the document.
341
+		 * @return string content of the PDF, if $dest=S
342
+		 * @see TCPDF::close
343
+		 * @access public
344
+		 */
345
+		public function Output($name = '', $dest = false)
346
+		{
347
+			// close the pdf and clean up
348
+			$this->_cleanUp();
349
+
350
+			// if on debug mode
351
+			if ($this->_debugActif) {
352
+				$this->_DEBUG_add('Before output');
353
+				$this->pdf->Close();
354
+				exit;
355
+			}
356
+
357
+			// complete parameters
358
+			if ($dest===false) $dest = 'I';
359
+			if ($dest===true)  $dest = 'S';
360
+			if ($dest==='')    $dest = 'I';
361
+			if ($name=='')     $name='document.pdf';
362
+
363
+			// clean up the destination
364
+			$dest = strtoupper($dest);
365
+			if (!in_array($dest, array('I', 'D', 'F', 'S', 'FI','FD'))) $dest = 'I';
366
+
367
+			// the name must be a PDF name
368
+			if (strtolower(substr($name, -4))!='.pdf') {
369
+				throw new HTML2PDF_exception(0, 'The output document name "'.$name.'" is not a PDF name');
370
+			}
371
+
372
+			// call the output of TCPDF
373
+			return $this->pdf->Output($name, $dest);
374
+		}
375
+
376
+		/**
377
+		 * convert HTML to PDF
378
+		 *
379
+		 * @access public
380
+		 * @param  string   $html
381
+		 * @param  boolean  $debugVue  enable the HTML debug vue
382
+		 * @return null
383
+		 */
384
+		public function writeHTML($html, $debugVue = false)
385
+		{
386
+			// if it is a real html page, we have to convert it
387
+			if (preg_match('/<body/isU', $html))
388
+				$html = $this->getHtmlFromPage($html);
389
+
390
+			$html = str_replace('[[date_y]]', date('Y'), $html);
391
+			$html = str_replace('[[date_m]]', date('m'), $html);
392
+			$html = str_replace('[[date_d]]', date('d'), $html);
393
+
394
+			$html = str_replace('[[date_h]]', date('H'), $html);
395
+			$html = str_replace('[[date_i]]', date('i'), $html);
396
+			$html = str_replace('[[date_s]]', date('s'), $html);
397
+
398
+			// If we are in HTML debug vue : display the HTML
399
+			if ($debugVue) {
400
+				return $this->_vueHTML($html);
401
+			}
402
+
403
+			// convert HTMl to PDF
404
+			$this->parsingCss->readStyle($html);
405
+			$this->parsingHtml->setHTML($html);
406
+			$this->parsingHtml->parse();
407
+			$this->_makeHTMLcode();
408
+		}
409
+
410
+		/**
411
+		 * convert the HTML of a real page, to a code adapted to HTML2PDF
412
+		 *
413
+		 * @access public
414
+		 * @param  string HTML of a real page
415
+		 * @return string HTML adapted to HTML2PDF
416
+		 */
417
+		public function getHtmlFromPage($html)
418
+		{
419
+			$html = str_replace('<BODY', '<body', $html);
420
+			$html = str_replace('</BODY', '</body', $html);
421
+
422
+			// extract the content
423
+			$res = explode('<body', $html);
424
+			if (count($res)<2) return $html;
425
+			$content = '<page'.$res[1];
426
+			$content = explode('</body', $content);
427
+			$content = $content[0].'</page>';
428
+
429
+			// extract the link tags
430
+			preg_match_all('/<link([^>]*)>/isU', $html, $match);
431
+			foreach ($match[0] as $src)
432
+				$content = $src.'</link>'.$content;
433
+
434
+			// extract the css style tags
435
+			preg_match_all('/<style[^>]*>(.*)<\/style[^>]*>/isU', $html, $match);
436
+			foreach ($match[0] as $src)
437
+				$content = $src.$content;
438
+
439
+			return $content;
440
+		}
441
+
442
+		/**
443
+		 * init a sub HTML2PDF. does not use it directly. Only the method createSubHTML must use it
444
+		 *
445
+		 * @access public
446
+		 * @param  string  $format
447
+		 * @param  string  $orientation
448
+		 * @param  array   $marge
449
+		 * @param  integer $page
450
+		 * @param  array   $defLIST
451
+		 * @param  integer $myLastPageGroup
452
+		 * @param  integer $myLastPageGroupNb
453
+		 */
454
+		public function initSubHtml($format, $orientation, $marge, $page, $defLIST, $myLastPageGroup, $myLastPageGroupNb)
455
+		{
456
+			$this->_isSubPart = true;
457
+
458
+			$this->parsingCss->setOnlyLeft();
459
+
460
+			$this->_setNewPage($format, $orientation, null, null, ($myLastPageGroup!==null));
461
+
462
+			$this->_saveMargin(0, 0, $marge);
463
+			$this->_defList = $defLIST;
464
+
465
+			$this->_page = $page;
466
+			$this->pdf->setMyLastPageGroup($myLastPageGroup);
467
+			$this->pdf->setMyLastPageGroupNb($myLastPageGroupNb);
468
+			$this->pdf->setXY(0, 0);
469
+			$this->parsingCss->fontSet();
470
+		}
471
+
472
+		/**
473
+		 * display the content in HTML moden for debug
474
+		 *
475
+		 * @access protected
476
+		 * @param  string $contenu
477
+		 */
478
+		protected function _vueHTML($content)
479
+		{
480
+			$content = preg_replace('/<page_header([^>]*)>/isU', '<hr>'.HTML2PDF_locale::get('vue01').' : $1<hr><div$1>', $content);
481
+			$content = preg_replace('/<page_footer([^>]*)>/isU', '<hr>'.HTML2PDF_locale::get('vue02').' : $1<hr><div$1>', $content);
482
+			$content = preg_replace('/<page([^>]*)>/isU', '<hr>'.HTML2PDF_locale::get('vue03').' : $1<hr><div$1>', $content);
483
+			$content = preg_replace('/<\/page([^>]*)>/isU', '</div><hr>', $content);
484
+			$content = preg_replace('/<bookmark([^>]*)>/isU', '<hr>bookmark : $1<hr>', $content);
485
+			$content = preg_replace('/<\/bookmark([^>]*)>/isU', '', $content);
486
+			$content = preg_replace('/<barcode([^>]*)>/isU', '<hr>barcode : $1<hr>', $content);
487
+			$content = preg_replace('/<\/barcode([^>]*)>/isU', '', $content);
488
+			$content = preg_replace('/<qrcode([^>]*)>/isU', '<hr>qrcode : $1<hr>', $content);
489
+			$content = preg_replace('/<\/qrcode([^>]*)>/isU', '', $content);
490
+
491
+			echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
493 492
 <html>
494 493
     <head>
495 494
         <title>'.HTML2PDF_locale::get('vue04').' HTML</title>
@@ -499,5991 +498,5991 @@  discard block
 block discarded – undo
499 498
 '.$content.'
500 499
     </body>
501 500
 </html>';
502
-            exit;
503
-        }
504
-
505
-        /**
506
-         * set the default margins of the page
507
-         *
508
-         * @access protected
509
-         * @param  int $left   (mm, left margin)
510
-         * @param  int $top    (mm, top margin)
511
-         * @param  int $right  (mm, right margin, if null => left=right)
512
-         * @param  int $bottom (mm, bottom margin, if null => bottom=8mm)
513
-         */
514
-        protected function _setDefaultMargins($left, $top, $right = null, $bottom = null)
515
-        {
516
-            if ($right===null)  $right = $left;
517
-            if ($bottom===null) $bottom = 8;
518
-
519
-            $this->_defaultLeft   = $this->parsingCss->ConvertToMM($left.'mm');
520
-            $this->_defaultTop    = $this->parsingCss->ConvertToMM($top.'mm');
521
-            $this->_defaultRight  = $this->parsingCss->ConvertToMM($right.'mm');
522
-            $this->_defaultBottom = $this->parsingCss->ConvertToMM($bottom.'mm');
523
-        }
524
-
525
-        /**
526
-         * create a new page
527
-         *
528
-         * @access protected
529
-         * @param  mixed   $format
530
-         * @param  string  $orientation
531
-         * @param  array   $background background information
532
-         * @param  integer $curr real position in the html parseur (if break line in the write of a text)
533
-         * @param  boolean $resetPageNumber
534
-         */
535
-        protected function _setNewPage($format = null, $orientation = '', $background = null, $curr = null, $resetPageNumber=false)
536
-        {
537
-            $this->_firstPage = false;
538
-
539
-            $this->_format = $format ? $format : $this->_format;
540
-            $this->_orientation = $orientation ? $orientation : $this->_orientation;
541
-            $this->_background = $background!==null ? $background : $this->_background;
542
-            $this->_maxY = 0;
543
-            $this->_maxX = 0;
544
-            $this->_maxH = 0;
545
-            $this->_maxE = 0;
546
-
547
-            $this->pdf->SetMargins($this->_defaultLeft, $this->_defaultTop, $this->_defaultRight);
548
-
549
-            if ($resetPageNumber) {
550
-                $this->pdf->startPageGroup();
551
-            }
552
-
553
-            $this->pdf->AddPage($this->_orientation, $this->_format);
554
-
555
-            if ($resetPageNumber) {
556
-                $this->pdf->myStartPageGroup();
557
-            }
558
-
559
-            $this->_page++;
560
-
561
-            if (!$this->_subPart && !$this->_isSubPart) {
562
-                if (is_array($this->_background)) {
563
-                    if (isset($this->_background['color']) && $this->_background['color']) {
564
-                        $this->pdf->setFillColorArray($this->_background['color']);
565
-                        $this->pdf->Rect(0, 0, $this->pdf->getW(), $this->pdf->getH(), 'F');
566
-                    }
567
-
568
-                    if (isset($this->_background['img']) && $this->_background['img'])
569
-                        $this->pdf->Image($this->_background['img'], $this->_background['posX'], $this->_background['posY'], $this->_background['width']);
570
-                }
571
-
572
-                $this->_setPageHeader();
573
-                $this->_setPageFooter();
574
-            }
575
-
576
-            $this->_setMargins();
577
-            $this->pdf->setY($this->_margeTop);
578
-
579
-            $this->_setNewPositionForNewLine($curr);
580
-            $this->_maxH = 0;
581
-        }
582
-
583
-        /**
584
-         * set the real margin, using the default margins and the page margins
585
-         *
586
-         * @access protected
587
-         */
588
-        protected function _setMargins()
589
-        {
590
-            // prepare the margins
591
-            $this->_margeLeft   = $this->_defaultLeft   + (isset($this->_background['left'])   ? $this->_background['left']   : 0);
592
-            $this->_margeRight  = $this->_defaultRight  + (isset($this->_background['right'])  ? $this->_background['right']  : 0);
593
-            $this->_margeTop    = $this->_defaultTop    + (isset($this->_background['top'])    ? $this->_background['top']    : 0);
594
-            $this->_margeBottom = $this->_defaultBottom + (isset($this->_background['bottom']) ? $this->_background['bottom'] : 0);
595
-
596
-            // set the PDF margins
597
-            $this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
598
-            $this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
599
-
600
-            // set the float Margins
601
-            $this->_pageMarges = array();
602
-            if ($this->_isInParagraph!==false) {
603
-                $this->_pageMarges[floor($this->_margeTop*100)] = array($this->_isInParagraph[0], $this->pdf->getW()-$this->_isInParagraph[1]);
604
-            } else {
605
-                $this->_pageMarges[floor($this->_margeTop*100)] = array($this->_margeLeft, $this->pdf->getW()-$this->_margeRight);
606
-            }
607
-        }
608
-
609
-        /**
610
-         * add a debug step
611
-         *
612
-         * @access protected
613
-         * @param  string  $name step name
614
-         * @param  boolean $level (true=up, false=down, null=nothing to do)
615
-         * @return $this
616
-         */
617
-        protected function _DEBUG_add($name, $level=null)
618
-        {
619
-            // if true : UP
620
-            if ($level===true) $this->_debugLevel++;
621
-
622
-            $name   = str_repeat('  ', $this->_debugLevel). $name.($level===true ? ' Begin' : ($level===false ? ' End' : ''));
623
-            $time  = microtime(true);
624
-            $usage = ($this->_debugOkUsage ? memory_get_usage() : 0);
625
-            $peak  = ($this->_debugOkPeak ? memory_get_peak_usage() : 0);
626
-
627
-            $this->_DEBUG_stepline(
628
-                $name,
629
-                number_format(($time - $this->_debugStartTime)*1000, 1, '.', ' ').' ms',
630
-                number_format(($time - $this->_debugLastTime)*1000, 1, '.', ' ').' ms',
631
-                number_format($usage/1024, 1, '.', ' ').' Ko',
632
-                number_format($peak/1024, 1, '.', ' ').' Ko'
633
-            );
634
-
635
-            $this->_debugLastTime = $time;
636
-
637
-            // it false : DOWN
638
-            if ($level===false) $this->_debugLevel--;
639
-
640
-            return $this;
641
-        }
642
-
643
-        /**
644
-         * display a debug line
645
-         *
646
-         *
647
-         * @access protected
648
-         * @param  string $name
649
-         * @param  string $timeTotal
650
-         * @param  string $timeStep
651
-         * @param  string $memoryUsage
652
-         * @param  string $memoryPeak
653
-         */
654
-        protected function _DEBUG_stepline($name, $timeTotal, $timeStep, $memoryUsage, $memoryPeak)
655
-        {
656
-            $txt = str_pad($name, 30, ' ', STR_PAD_RIGHT).
657
-                    str_pad($timeTotal, 12, ' ', STR_PAD_LEFT).
658
-                    str_pad($timeStep, 12, ' ', STR_PAD_LEFT).
659
-                    str_pad($memoryUsage, 15, ' ', STR_PAD_LEFT).
660
-                    str_pad($memoryPeak, 15, ' ', STR_PAD_LEFT);
661
-
662
-            echo '<pre style="padding:0; margin:0">'.$txt.'</pre>';
663
-        }
664
-
665
-        /**
666
-         * get the Min and Max X, for Y (use the float margins)
667
-         *
668
-         * @access protected
669
-         * @param  float $y
670
-         * @return array(float, float)
671
-         */
672
-        protected function _getMargins($y)
673
-        {
674
-            $y = floor($y*100);
675
-            $x = array($this->pdf->getlMargin(), $this->pdf->getW()-$this->pdf->getrMargin());
676
-
677
-            foreach ($this->_pageMarges as $mY => $mX)
678
-                if ($mY<=$y) $x = $mX;
679
-
680
-            return $x;
681
-        }
682
-
683
-        /**
684
-         * Add margins, for a float
685
-         *
686
-         * @access protected
687
-         * @param  string $float (left / right)
688
-         * @param  float  $xLeft
689
-         * @param  float  $yTop
690
-         * @param  float  $xRight
691
-         * @param  float  $yBottom
692
-         */
693
-        protected function _addMargins($float, $xLeft, $yTop, $xRight, $yBottom)
694
-        {
695
-            // get the current float margins, for top and bottom
696
-            $oldTop    = $this->_getMargins($yTop);
697
-            $oldBottom = $this->_getMargins($yBottom);
698
-
699
-            // update the top float margin
700
-            if ($float=='left'  && $oldTop[0]<$xRight) $oldTop[0] = $xRight;
701
-            if ($float=='right' && $oldTop[1]>$xLeft)  $oldTop[1] = $xLeft;
702
-
703
-            $yTop = floor($yTop*100);
704
-            $yBottom = floor($yBottom*100);
705
-
706
-            // erase all the float margins that are smaller than the new one
707
-            foreach ($this->_pageMarges as $mY => $mX) {
708
-                if ($mY<$yTop) continue;
709
-                if ($mY>$yBottom) break;
710
-                if ($float=='left' && $this->_pageMarges[$mY][0]<$xRight)  unset($this->_pageMarges[$mY]);
711
-                if ($float=='right' && $this->_pageMarges[$mY][1]>$xLeft) unset($this->_pageMarges[$mY]);
712
-            }
713
-
714
-            // save the new Top and Bottom margins
715
-            $this->_pageMarges[$yTop] = $oldTop;
716
-            $this->_pageMarges[$yBottom] = $oldBottom;
717
-
718
-            // sort the margins
719
-            ksort($this->_pageMarges);
720
-
721
-            // we are just after float
722
-            $this->_isAfterFloat = true;
723
-        }
724
-
725
-        /**
726
-         * Save old margins (push), and set new ones
727
-         *
728
-         * @access protected
729
-         * @param  float  $ml left margin
730
-         * @param  float  $mt top margin
731
-         * @param  float  $mr right margin
732
-         */
733
-        protected function _saveMargin($ml, $mt, $mr)
734
-        {
735
-            // save old margins
736
-            $this->_marges[] = array('l' => $this->pdf->getlMargin(), 't' => $this->pdf->gettMargin(), 'r' => $this->pdf->getrMargin(), 'page' => $this->_pageMarges);
737
-
738
-            // set new ones
739
-            $this->pdf->SetMargins($ml, $mt, $mr);
740
-
741
-            // prepare for float margins
742
-            $this->_pageMarges = array();
743
-            $this->_pageMarges[floor($mt*100)] = array($ml, $this->pdf->getW()-$mr);
744
-        }
745
-
746
-        /**
747
-         * load the last saved margins (pop)
748
-         *
749
-         * @access protected
750
-         */
751
-        protected function _loadMargin()
752
-        {
753
-            $old = array_pop($this->_marges);
754
-            if ($old) {
755
-                $ml = $old['l'];
756
-                $mt = $old['t'];
757
-                $mr = $old['r'];
758
-                $mP = $old['page'];
759
-            } else {
760
-                $ml = $this->_margeLeft;
761
-                $mt = 0;
762
-                $mr = $this->_margeRight;
763
-                $mP = array($mt => array($ml, $this->pdf->getW()-$mr));
764
-            }
765
-
766
-            $this->pdf->SetMargins($ml, $mt, $mr);
767
-            $this->_pageMarges = $mP;
768
-        }
769
-
770
-        /**
771
-         * save the current maxs (push)
772
-         *
773
-         * @access protected
774
-         */
775
-        protected function _saveMax()
776
-        {
777
-            $this->_maxSave[] = array($this->_maxX, $this->_maxY, $this->_maxH, $this->_maxE);
778
-        }
779
-
780
-        /**
781
-         * load the last saved current maxs (pop)
782
-         *
783
-         * @access protected
784
-         */
785
-        protected function _loadMax()
786
-        {
787
-            $old = array_pop($this->_maxSave);
788
-
789
-            if ($old) {
790
-                $this->_maxX = $old[0];
791
-                $this->_maxY = $old[1];
792
-                $this->_maxH = $old[2];
793
-                $this->_maxE = $old[3];
794
-            } else {
795
-                $this->_maxX = 0;
796
-                $this->_maxY = 0;
797
-                $this->_maxH = 0;
798
-                $this->_maxE = 0;
799
-            }
800
-        }
801
-
802
-        /**
803
-         * draw the PDF header with the HTML in page_header
804
-         *
805
-         * @access protected
806
-         */
807
-        protected function _setPageHeader()
808
-        {
809
-            if (!count($this->_subHEADER)) return false;
810
-
811
-            $oldParsePos = $this->_parsePos;
812
-            $oldParseCode = $this->parsingHtml->code;
813
-
814
-            $this->_parsePos = 0;
815
-            $this->parsingHtml->code = $this->_subHEADER;
816
-            $this->_makeHTMLcode();
817
-
818
-            $this->_parsePos = $oldParsePos;
819
-            $this->parsingHtml->code = $oldParseCode;
820
-        }
821
-
822
-        /**
823
-         * draw the PDF footer with the HTML in page_footer
824
-         *
825
-         * @access protected
826
-         */
827
-        protected function _setPageFooter()
828
-        {
829
-            if (!count($this->_subFOOTER)) return false;
830
-
831
-            $oldParsePos = $this->_parsePos;
832
-            $oldParseCode = $this->parsingHtml->code;
833
-
834
-            $this->_parsePos = 0;
835
-            $this->parsingHtml->code = $this->_subFOOTER;
836
-            $this->_isInFooter = true;
837
-            $this->_makeHTMLcode();
838
-            $this->_isInFooter = false;
839
-
840
-            $this->_parsePos = $oldParsePos;
841
-            $this->parsingHtml->code = $oldParseCode;
842
-        }
843
-
844
-        /**
845
-         * new line, with a specific height
846
-         *
847
-         * @access protected
848
-         * @param float   $h
849
-         * @param integer $curr real current position in the text, if new line in the write of a text
850
-         */
851
-        protected function _setNewLine($h, $curr = null)
852
-        {
853
-            $this->pdf->Ln($h);
854
-            $this->_setNewPositionForNewLine($curr);
855
-        }
856
-
857
-        /**
858
-         * calculate the start position of the next line,  depending on the text-align
859
-         *
860
-         * @access protected
861
-         * @param  integer $curr real current position in the text, if new line in the write of a text
862
-         */
863
-        protected function _setNewPositionForNewLine($curr = null)
864
-        {
865
-            // get the margins for the current line
866
-            list($lx, $rx) = $this->_getMargins($this->pdf->getY());
867
-            $this->pdf->setX($lx);
868
-            $wMax = $rx-$lx;
869
-            $this->_currentH = 0;
870
-
871
-            // if subPart => return because align left
872
-            if ($this->_subPart || $this->_isSubPart || $this->_isForOneLine) {
873
-                $this->pdf->setWordSpacing(0);
874
-                return null;
875
-            }
876
-
877
-            // create the sub object
878
-            $sub = null;
879
-            $this->_createSubHTML($sub);
880
-            $sub->_saveMargin(0, 0, $sub->pdf->getW()-$wMax);
881
-            $sub->_isForOneLine = true;
882
-            $sub->_parsePos = $this->_parsePos;
883
-            $sub->parsingHtml->code = $this->parsingHtml->code;
884
-
885
-            // if $curr => adapt the current position of the parsing
886
-            if ($curr!==null && $sub->parsingHtml->code[$this->_parsePos]['name']=='write') {
887
-                $txt = $sub->parsingHtml->code[$this->_parsePos]['param']['txt'];
888
-                $txt = str_replace('[[page_cu]]', $sub->pdf->getMyNumPage($this->_page), $txt);
889
-                $sub->parsingHtml->code[$this->_parsePos]['param']['txt'] = substr($txt, $curr+1);
890
-            } else
891
-                $sub->_parsePos++;
892
-
893
-            // for each element of the parsing => load the action
894
-            $res = null;
895
-            for ($sub->_parsePos; $sub->_parsePos<count($sub->parsingHtml->code); $sub->_parsePos++) {
896
-                $action = $sub->parsingHtml->code[$sub->_parsePos];
897
-                $res = $sub->_executeAction($action);
898
-                if (!$res) break;
899
-            }
900
-
901
-            $w = $sub->_maxX; // max width
902
-            $h = $sub->_maxH; // max height
903
-            $e = ($res===null ? $sub->_maxE : 0); // maxnumber of elemets on the line
904
-
905
-            // destroy the sub HTML
906
-            $this->_destroySubHTML($sub);
907
-
908
-            // adapt the start of the line, depending on the text-align
909
-            if ($this->parsingCss->value['text-align']=='center')
910
-                $this->pdf->setX(($rx+$this->pdf->getX()-$w)*0.5-0.01);
911
-            else if ($this->parsingCss->value['text-align']=='right')
912
-                $this->pdf->setX($rx-$w-0.01);
913
-            else
914
-                $this->pdf->setX($lx);
915
-
916
-            // set the height of the line
917
-            $this->_currentH = $h;
918
-
919
-            // if justify => set the word spacing
920
-            if ($this->parsingCss->value['text-align']=='justify' && $e>1) {
921
-                $this->pdf->setWordSpacing(($wMax-$w)/($e-1));
922
-            } else {
923
-                $this->pdf->setWordSpacing(0);
924
-            }
925
-        }
926
-
927
-        /**
928
-         * prepare HTML2PDF::$_subobj (used for create the sub HTML2PDF objects
929
-         *
930
-         * @access protected
931
-         */
932
-        protected function _prepareSubObj()
933
-        {
934
-            $pdf = null;
935
-
936
-            // create the sub object
937
-            HTML2PDF::$_subobj = new HTML2PDF(
938
-                                        $this->_orientation,
939
-                                        $this->_format,
940
-                                        $this->_langue,
941
-                                        $this->_unicode,
942
-                                        $this->_encoding,
943
-                                        array($this->_defaultLeft,$this->_defaultTop,$this->_defaultRight,$this->_defaultBottom)
944
-                                    );
945
-
946
-            // init
947
-            HTML2PDF::$_subobj->setTestTdInOnePage($this->_testTdInOnepage);
948
-            HTML2PDF::$_subobj->setTestIsImage($this->_testIsImage);
949
-            HTML2PDF::$_subobj->setTestIsDeprecated($this->_testIsDeprecated);
950
-            HTML2PDF::$_subobj->setDefaultFont($this->_defaultFont);
951
-            HTML2PDF::$_subobj->parsingCss->css            = &$this->parsingCss->css;
952
-            HTML2PDF::$_subobj->parsingCss->cssKeys        = &$this->parsingCss->cssKeys;
953
-
954
-            // clone font from the original PDF
955
-            HTML2PDF::$_subobj->pdf->cloneFontFrom($this->pdf);
956
-
957
-            // remove the link to the parent
958
-            HTML2PDF::$_subobj->parsingCss->setPdfParent($pdf);
959
-        }
960
-
961
-        /**
962
-         * create a sub HTML2PDF, to calculate the multi-tables
963
-         *
964
-         * @access protected
965
-         * @param  &HTML2PDF $subHtml sub HTML2PDF to create
966
-         * @param  integer   $cellmargin if in a TD : cellmargin of this td
967
-         */
968
-        protected function _createSubHTML(&$subHtml, $cellmargin=0)
969
-        {
970
-            // prepare the subObject, if never prepare before
971
-            if (HTML2PDF::$_subobj===null) {
972
-                $this->_prepareSubObj();
973
-            }
974
-
975
-            // calculate the width to use
976
-            if ($this->parsingCss->value['width']) {
977
-                $marge = $cellmargin*2;
978
-                $marge+= $this->parsingCss->value['padding']['l'] + $this->parsingCss->value['padding']['r'];
979
-                $marge+= $this->parsingCss->value['border']['l']['width'] + $this->parsingCss->value['border']['r']['width'];
980
-                $marge = $this->pdf->getW() - $this->parsingCss->value['width'] + $marge;
981
-            } else {
982
-                $marge = $this->_margeLeft+$this->_margeRight;
983
-            }
984
-
985
-            // BUGFIX : we have to call the method, because of a bug in php 5.1.6
986
-            HTML2PDF::$_subobj->pdf->getPage();
987
-
988
-            // clone the sub oject
989
-            $subHtml = clone HTML2PDF::$_subobj;
990
-            $subHtml->parsingCss->table = $this->parsingCss->table;
991
-            $subHtml->parsingCss->value = $this->parsingCss->value;
992
-            $subHtml->initSubHtml(
993
-                $this->_format,
994
-                $this->_orientation,
995
-                $marge,
996
-                $this->_page,
997
-                $this->_defList,
998
-                $this->pdf->getMyLastPageGroup(),
999
-                $this->pdf->getMyLastPageGroupNb()
1000
-            );
1001
-        }
1002
-
1003
-        /**
1004
-         * destroy a subHTML2PDF
1005
-         *
1006
-         * @access protected
1007
-         */
1008
-        protected function _destroySubHTML(&$subHtml)
1009
-        {
1010
-            unset($subHtml);
1011
-            $subHtml = null;
1012
-        }
1013
-
1014
-        /**
1015
-         * Convert a arabic number in roman number
1016
-         *
1017
-         * @access protected
1018
-         * @param  integer $nbArabic
1019
-         * @return string  $nbRoman
1020
-         */
1021
-        protected function _listeArab2Rom($nbArabic)
1022
-        {
1023
-            $nbBaseTen    = array('I','X','C','M');
1024
-            $nbBaseFive    = array('V','L','D');
1025
-            $nbRoman    = '';
1026
-
1027
-            if ($nbArabic<1)    return $nbArabic;
1028
-            if ($nbArabic>3999) return $nbArabic;
1029
-
1030
-            for ($i=3; $i>=0 ; $i--) {
1031
-                $chiffre=floor($nbArabic/pow(10, $i));
1032
-                if ($chiffre>=1) {
1033
-                    $nbArabic=$nbArabic-$chiffre*pow(10, $i);
1034
-                    if ($chiffre<=3) {
1035
-                        for ($j=$chiffre; $j>=1; $j--) {
1036
-                            $nbRoman=$nbRoman.$nbBaseTen[$i];
1037
-                        }
1038
-                    } else if ($chiffre==9) {
1039
-                        $nbRoman=$nbRoman.$nbBaseTen[$i].$nbBaseTen[$i+1];
1040
-                    } else if ($chiffre==4) {
1041
-                    $nbRoman=$nbRoman.$nbBaseTen[$i].$nbBaseFive[$i];
1042
-                    } else {
1043
-                        $nbRoman=$nbRoman.$nbBaseFive[$i];
1044
-                        for ($j=$chiffre-5; $j>=1; $j--) {
1045
-                            $nbRoman=$nbRoman.$nbBaseTen[$i];
1046
-                        }
1047
-                    }
1048
-                }
1049
-            }
1050
-            return $nbRoman;
1051
-        }
1052
-
1053
-        /**
1054
-         * add a LI to the current level
1055
-         *
1056
-         * @access protected
1057
-         */
1058
-        protected function _listeAddLi()
1059
-        {
1060
-            $this->_defList[count($this->_defList)-1]['nb']++;
1061
-        }
1062
-
1063
-        /**
1064
-         * get the width to use for the column of the list
1065
-         *
1066
-         * @access protected
1067
-         * @return string $width
1068
-         */
1069
-        protected function _listeGetWidth()
1070
-        {
1071
-            return '7mm';
1072
-        }
1073
-
1074
-        /**
1075
-         * get the padding to use for the column of the list
1076
-         *
1077
-         * @access protected
1078
-         * @return string $padding
1079
-         */
1080
-        protected function _listeGetPadding()
1081
-        {
1082
-            return '1mm';
1083
-        }
1084
-
1085
-        /**
1086
-         * get the information of the li on the current level
1087
-         *
1088
-         * @access protected
1089
-         * @return array(fontName, small size, string)
1090
-         */
1091
-        protected function _listeGetLi()
1092
-        {
1093
-            $im = $this->_defList[count($this->_defList)-1]['img'];
1094
-            $st = $this->_defList[count($this->_defList)-1]['style'];
1095
-            $nb = $this->_defList[count($this->_defList)-1]['nb'];
1096
-            $up = (substr($st, 0, 6)=='upper-');
1097
-
1098
-            if ($im) return array(false, false, $im);
1099
-
1100
-            switch($st)
1101
-            {
1102
-                case 'none':
1103
-                    return array('helvetica', true, ' ');
1104
-
1105
-                case 'upper-alpha':
1106
-                case 'lower-alpha':
1107
-                    $str = '';
1108
-                    while ($nb>26) {
1109
-                        $str = chr(96+$nb%26).$str;
1110
-                        $nb = floor($nb/26);
1111
-                    }
1112
-                    $str = chr(96+$nb).$str;
1113
-
1114
-                    return array('helvetica', false, ($up ? strtoupper($str) : $str).'.');
1115
-
1116
-                case 'upper-roman':
1117
-                case 'lower-roman':
1118
-                    $str = $this->_listeArab2Rom($nb);
1119
-
1120
-                    return array('helvetica', false, ($up ? strtoupper($str) : $str).'.');
1121
-
1122
-                case 'decimal':
1123
-                    return array('helvetica', false, $nb.'.');
1124
-
1125
-                case 'square':
1126
-                    return array('zapfdingbats', true, chr(110));
1127
-
1128
-                case 'circle':
1129
-                    return array('zapfdingbats', true, chr(109));
1130
-
1131
-                case 'disc':
1132
-                default:
1133
-                    return array('zapfdingbats', true, chr(108));
1134
-            }
1135
-        }
1136
-
1137
-        /**
1138
-         * add a level to the list
1139
-         *
1140
-         * @access protected
1141
-         * @param  string $type  : ul, ol
1142
-         * @param  string $style : lower-alpha, ...
1143
-         * @param  string $img
1144
-         */
1145
-        protected function _listeAddLevel($type = 'ul', $style = '', $img = null)
1146
-        {
1147
-            // get the url of the image, if we want to use a image
1148
-            if ($img) {
1149
-                if (preg_match('/^url\(([^)]+)\)$/isU', trim($img), $match)) {
1150
-                    $img = $match[1];
1151
-                } else {
1152
-                    $img = null;
1153
-                }
1154
-            } else {
1155
-                $img = null;
1156
-            }
1157
-
1158
-            // prepare the datas
1159
-            if (!in_array($type, array('ul', 'ol'))) $type = 'ul';
1160
-            if (!in_array($style, array('lower-alpha', 'upper-alpha', 'upper-roman', 'lower-roman', 'decimal', 'square', 'circle', 'disc', 'none'))) $style = '';
1161
-
1162
-            if (!$style) {
1163
-                if ($type=='ul')    $style = 'disc';
1164
-                else                $style = 'decimal';
1165
-            }
1166
-
1167
-            // add the new level
1168
-            $this->_defList[count($this->_defList)] = array('style' => $style, 'nb' => 0, 'img' => $img);
1169
-        }
1170
-
1171
-        /**
1172
-         * remove a level to the list
1173
-         *
1174
-         * @access protected
1175
-         */
1176
-        protected function _listeDelLevel()
1177
-        {
1178
-            if (count($this->_defList)) {
1179
-                unset($this->_defList[count($this->_defList)-1]);
1180
-                $this->_defList = array_values($this->_defList);
1181
-            }
1182
-        }
1183
-
1184
-        /**
1185
-         * execute the actions to convert the html
1186
-         *
1187
-         * @access protected
1188
-         */
1189
-        protected function _makeHTMLcode()
1190
-        {
1191
-            // foreach elements of the parsing
1192
-            for ($this->_parsePos=0; $this->_parsePos<count($this->parsingHtml->code); $this->_parsePos++) {
1193
-
1194
-                // get the action to do
1195
-                $action = $this->parsingHtml->code[$this->_parsePos];
1196
-
1197
-                // if it is a opening of table / ul / ol
1198
-                if (in_array($action['name'], array('table', 'ul', 'ol')) && !$action['close']) {
1199
-
1200
-                    //  we will work as a sub HTML to calculate the size of the element
1201
-                    $this->_subPart = true;
1202
-
1203
-                    // get the name of the opening tag
1204
-                    $tagOpen = $action['name'];
1205
-
1206
-                    // save the actual pos on the parsing
1207
-                    $this->_tempPos = $this->_parsePos;
1208
-
1209
-                    // foreach elements, while we are in the opened tag
1210
-                    while (isset($this->parsingHtml->code[$this->_tempPos]) && !($this->parsingHtml->code[$this->_tempPos]['name']==$tagOpen && $this->parsingHtml->code[$this->_tempPos]['close'])) {
1211
-                        // make the action
1212
-                        $this->_executeAction($this->parsingHtml->code[$this->_tempPos]);
1213
-                        $this->_tempPos++;
1214
-                    }
1215
-
1216
-                    // execute the closure of the tag
1217
-                    if (isset($this->parsingHtml->code[$this->_tempPos])) {
1218
-                        $this->_executeAction($this->parsingHtml->code[$this->_tempPos]);
1219
-                    }
1220
-
1221
-                    // end of the sub part
1222
-                    $this->_subPart = false;
1223
-                }
1224
-
1225
-                // execute the action
1226
-                $this->_executeAction($action);
1227
-            }
1228
-        }
1229
-
1230
-        /**
1231
-         * execute the action from the parsing
1232
-         *
1233
-         * @access protected
1234
-         * @param  array $action
1235
-         */
1236
-        protected function _executeAction($action)
1237
-        {
1238
-            // name of the action
1239
-            $fnc = ($action['close'] ? '_tag_close_' : '_tag_open_').strtoupper($action['name']);
1240
-
1241
-            // parameters of the action
1242
-            $param = $action['param'];
1243
-
1244
-            // if it the first action of the first page, and if it is not a open tag of PAGE => create the new page
1245
-            if ($fnc!='_tag_open_PAGE' && $this->_firstPage) {
1246
-                $this->_setNewPage();
1247
-            }
1248
-
1249
-            // the action must exist
1250
-            if (!is_callable(array(&$this, $fnc))) {
1251
-                throw new HTML2PDF_exception(1, strtoupper($action['name']), $this->parsingHtml->getHtmlErrorCode($action['html_pos']));
1252
-            }
1253
-
1254
-            // lauch the action
1255
-            $res = $this->{$fnc}($param);
1256
-
1257
-            // save the name of the action
1258
-            $this->_previousCall = $fnc;
1259
-
1260
-            // return the result
1261
-            return $res;
1262
-        }
1263
-
1264
-        /**
1265
-         * get the position of the element on the current line, depending on his height
1266
-         *
1267
-         * @access protected
1268
-         * @param  float $h
1269
-         * @return float
1270
-         */
1271
-        protected function _getElementY($h)
1272
-        {
1273
-            if ($this->_subPart || $this->_isSubPart || !$this->_currentH || $this->_currentH<$h)
1274
-                return 0;
1275
-
1276
-            return ($this->_currentH-$h)*0.8;
1277
-        }
1278
-
1279
-        /**
1280
-         * make a break line
1281
-         *
1282
-         * @access protected
1283
-         * @param  float $h current line height
1284
-         * @param  integer $curr real current position in the text, if new line in the write of a text
1285
-         */
1286
-        protected function _makeBreakLine($h, $curr = null)
1287
-        {
1288
-            if ($h) {
1289
-                if (($this->pdf->getY()+$h<$this->pdf->getH() - $this->pdf->getbMargin()) || $this->_isInOverflow || $this->_isInFooter)
1290
-                    $this->_setNewLine($h, $curr);
1291
-                else
1292
-                    $this->_setNewPage(null, '', null, $curr);
1293
-            } else {
1294
-                $this->_setNewPositionForNewLine($curr);
1295
-            }
1296
-
1297
-            $this->_maxH = 0;
1298
-            $this->_maxE = 0;
1299
-        }
1300
-
1301
-        /**
1302
-         * display a image
1303
-         *
1304
-         * @access protected
1305
-         * @param  string $src
1306
-         * @param  boolean $subLi if true=image of a list
1307
-         * @return boolean depending on "isForOneLine"
1308
-         */
1309
-        protected function _drawImage($src, $subLi=false)
1310
-        {
1311
-            // get the size of the image
1312
-            // WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
1313
-
1314
-            $infos=@getimagesize($src);
1315
-
1316
-            // if the image does not exist, or can not be loaded
1317
-            if (count($infos)<2) {
1318
-                // if the test is activ => exception
1319
-                if ($this->_testIsImage) {
1320
-                    throw new HTML2PDF_exception(6, $src);
1321
-                }
1322
-
1323
-                // else, display a gray rectangle
1324
-                $src = null;
1325
-                $infos = array(16, 16);
1326
-            }
1327
-
1328
-            // convert the size of the image in the unit of the PDF
1329
-            $imageWidth = $infos[0]/$this->pdf->getK();
1330
-            $imageHeight = $infos[1]/$this->pdf->getK();
1331
-
1332
-            // calculate the size from the css style
1333
-            if ($this->parsingCss->value['width'] && $this->parsingCss->value['height']) {
1334
-                $w = $this->parsingCss->value['width'];
1335
-                $h = $this->parsingCss->value['height'];
1336
-            } else if ($this->parsingCss->value['width']) {
1337
-                $w = $this->parsingCss->value['width'];
1338
-                $h = $imageHeight*$w/$imageWidth;
1339
-            } else if ($this->parsingCss->value['height']) {
1340
-                $h = $this->parsingCss->value['height'];
1341
-                $w = $imageWidth*$h/$imageHeight;
1342
-            } else {
1343
-                // convert px to pt
1344
-                $w = 72./96.*$imageWidth;
1345
-                $h = 72./96.*$imageHeight;
1346
-            }
1347
-
1348
-            // are we in a float
1349
-            $float = $this->parsingCss->getFloat();
1350
-
1351
-            // if we are in a float, but if something else if on the line => Break Line
1352
-            if ($float && $this->_maxH) {
1353
-                // make the break line (false if we are in "_isForOneLine" mode)
1354
-                if (!$this->_tag_open_BR(array())) {
1355
-                    return false;
1356
-                }
1357
-            }
1358
-
1359
-            // position of the image
1360
-            $x = $this->pdf->getX();
1361
-            $y = $this->pdf->getY();
1362
-
1363
-            // if the image can not be put on the current line => new line
1364
-            if (!$float && ($x + $w>$this->pdf->getW() - $this->pdf->getrMargin()) && $this->_maxH) {
1365
-                if ($this->_isForOneLine) {
1366
-                    return false;
1367
-                }
1368
-
1369
-                // set the new line
1370
-                $hnl = max($this->_maxH, $this->parsingCss->getLineHeight());
1371
-                $this->_setNewLine($hnl);
1372
-
1373
-                // get the new position
1374
-                $x = $this->pdf->getX();
1375
-                $y = $this->pdf->getY();
1376
-            }
1377
-
1378
-            // if the image can not be put on the current page
1379
-            if (($y + $h>$this->pdf->getH() - $this->pdf->getbMargin()) && !$this->_isInOverflow) {
1380
-                // new page
1381
-                $this->_setNewPage();
1382
-
1383
-                // get the new position
1384
-                $x = $this->pdf->getX();
1385
-                $y = $this->pdf->getY();
1386
-            }
1387
-
1388
-            // correction for display the image of a list
1389
-            $hT = 0.80*$this->parsingCss->value['font-size'];
1390
-            if ($subLi && $h<$hT) {
1391
-                $y+=($hT-$h);
1392
-            }
1393
-
1394
-            // add the margin top
1395
-            $yc = $y-$this->parsingCss->value['margin']['t'];
1396
-
1397
-            // get the width and the position of the parent
1398
-            $old = $this->parsingCss->getOldValues();
1399
-            if ( $old['width']) {
1400
-                $parentWidth = $old['width'];
1401
-                $parentX = $x;
1402
-            } else {
1403
-                $parentWidth = $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
1404
-                $parentX = $this->pdf->getlMargin();
1405
-            }
1406
-
1407
-            // if we are in a gloat => adapt the parent position and width
1408
-            if ($float) {
1409
-                list($lx, $rx) = $this->_getMargins($yc);
1410
-                $parentX = $lx;
1411
-                $parentWidth = $rx-$lx;
1412
-            }
1413
-
1414
-            // calculate the position of the image, if align to the right
1415
-            if ($parentWidth>$w && $float!='left') {
1416
-                if ($float=='right' || $this->parsingCss->value['text-align']=='li_right')    $x = $parentX + $parentWidth - $w-$this->parsingCss->value['margin']['r']-$this->parsingCss->value['margin']['l'];
1417
-            }
1418
-
1419
-            // display the image
1420
-            if (!$this->_subPart && !$this->_isSubPart) {
1421
-                if ($src) {
1422
-                    $this->pdf->Image($src, $x, $y, $w, $h, '', $this->_isInLink);
1423
-                } else {
1424
-                    // rectangle if the image can not be loaded
1425
-                    $this->pdf->setFillColorArray(array(240, 220, 220));
1426
-                    $this->pdf->Rect($x, $y, $w, $h, 'F');
1427
-                }
1428
-            }
1429
-
1430
-            // apply the margins
1431
-            $x-= $this->parsingCss->value['margin']['l'];
1432
-            $y-= $this->parsingCss->value['margin']['t'];
1433
-            $w+= $this->parsingCss->value['margin']['l'] + $this->parsingCss->value['margin']['r'];
1434
-            $h+= $this->parsingCss->value['margin']['t'] + $this->parsingCss->value['margin']['b'];
1435
-
1436
-            if ($float=='left') {
1437
-                // save the current max
1438
-                $this->_maxX = max($this->_maxX, $x+$w);
1439
-                $this->_maxY = max($this->_maxY, $y+$h);
1440
-
1441
-                // add the image to the margins
1442
-                $this->_addMargins($float, $x, $y, $x+$w, $y+$h);
1443
-
1444
-                // get the new position
1445
-                list($lx, $rx) = $this->_getMargins($yc);
1446
-                $this->pdf->setXY($lx, $yc);
1447
-            } else if ($float=='right') {
1448
-                // save the current max. We don't save the X because it is not the real max of the line
1449
-                $this->_maxY = max($this->_maxY, $y+$h);
1450
-
1451
-                // add the image to the margins
1452
-                $this->_addMargins($float, $x, $y, $x+$w, $y+$h);
1453
-
1454
-                // get the new position
1455
-                list($lx, $rx) = $this->_getMargins($yc);
1456
-                $this->pdf->setXY($lx, $yc);
1457
-            } else {
1458
-                // set the new position at the end of the image
1459
-                $this->pdf->setX($x+$w);
1460
-
1461
-                // save the current max
1462
-                $this->_maxX = max($this->_maxX, $x+$w);
1463
-                $this->_maxY = max($this->_maxY, $y+$h);
1464
-                $this->_maxH = max($this->_maxH, $h);
1465
-            }
1466
-
1467
-            return true;
1468
-        }
1469
-
1470
-        /**
1471
-         * draw a rectangle
1472
-         *
1473
-         * @access protected
1474
-         * @param  float $x
1475
-         * @param  float $y
1476
-         * @param  float $w
1477
-         * @param  float $h
1478
-         * @param  array $border
1479
-         * @param  float $padding - internal marge of the rectanble => not used, but...
1480
-         * @param  float $margin  - external marge of the rectanble
1481
-         * @param  array $background
1482
-         * @return boolean
1483
-         */
1484
-        protected function _drawRectangle($x, $y, $w, $h, $border, $padding, $margin, $background)
1485
-        {
1486
-            // if we are in a subpart or if height is null => return false
1487
-            if ($this->_subPart || $this->_isSubPart || $h===null) return false;
1488
-
1489
-            // add the margin
1490
-            $x+= $margin;
1491
-            $y+= $margin;
1492
-            $w-= $margin*2;
1493
-            $h-= $margin*2;
1494
-
1495
-            // get the radius of the border
1496
-            $outTL = $border['radius']['tl'];
1497
-            $outTR = $border['radius']['tr'];
1498
-            $outBR = $border['radius']['br'];
1499
-            $outBL = $border['radius']['bl'];
1500
-
1501
-            // prepare the out radius
1502
-            $outTL = ($outTL[0] && $outTL[1]) ? $outTL : null;
1503
-            $outTR = ($outTR[0] && $outTR[1]) ? $outTR : null;
1504
-            $outBR = ($outBR[0] && $outBR[1]) ? $outBR : null;
1505
-            $outBL = ($outBL[0] && $outBL[1]) ? $outBL : null;
1506
-
1507
-            // prepare the in radius
1508
-            $inTL = $outTL;
1509
-            $inTR = $outTR;
1510
-            $inBR = $outBR;
1511
-            $inBL = $outBL;
1512
-
1513
-            if (is_array($inTL)) {
1514
-                $inTL[0]-= $border['l']['width'];
1515
-                $inTL[1]-= $border['t']['width'];
1516
-            }
1517
-            if (is_array($inTR)) {
1518
-                $inTR[0]-= $border['r']['width'];
1519
-                $inTR[1]-= $border['t']['width'];
1520
-            }
1521
-            if (is_array($inBR)) {
1522
-                $inBR[0]-= $border['r']['width'];
1523
-                $inBR[1]-= $border['b']['width'];
1524
-            }
1525
-            if (is_array($inBL)) {
1526
-                $inBL[0]-= $border['l']['width'];
1527
-                $inBL[1]-= $border['b']['width'];
1528
-            }
1529
-
1530
-            if ($inTL[0]<=0 || $inTL[1]<=0) $inTL = null;
1531
-            if ($inTR[0]<=0 || $inTR[1]<=0) $inTR = null;
1532
-            if ($inBR[0]<=0 || $inBR[1]<=0) $inBR = null;
1533
-            if ($inBL[0]<=0 || $inBL[1]<=0) $inBL = null;
1534
-
1535
-            // prepare the background color
1536
-            $pdfStyle = '';
1537
-            if ($background['color']) {
1538
-                $this->pdf->setFillColorArray($background['color']);
1539
-                $pdfStyle.= 'F';
1540
-            }
1541
-
1542
-            // if we have a background to fill => fill it with a path (because of the radius)
1543
-            if ($pdfStyle) {
1544
-                $this->pdf->clippingPathStart($x, $y, $w, $h, $outTL, $outTR, $outBL, $outBR);
1545
-                $this->pdf->Rect($x, $y, $w, $h, $pdfStyle);
1546
-                $this->pdf->clippingPathStop();
1547
-            }
1548
-
1549
-            // prepare the background image
1550
-            if ($background['image']) {
1551
-                $iName      = $background['image'];
1552
-                $iPosition  = $background['position']!==null ? $background['position'] : array(0, 0);
1553
-                $iRepeat    = $background['repeat']!==null   ? $background['repeat']   : array(true, true);
1554
-
1555
-                // size of the background without the borders
1556
-                $bX = $x;
1557
-                $bY = $y;
1558
-                $bW = $w;
1559
-                $bH = $h;
1560
-
1561
-                if ($border['b']['width']) {
1562
-                    $bH-= $border['b']['width'];
1563
-                }
1564
-                if ($border['l']['width']) {
1565
-                    $bW-= $border['l']['width'];
1566
-                    $bX+= $border['l']['width'];
1567
-                }
1568
-                if ($border['t']['width']) {
1569
-                    $bH-= $border['t']['width'];
1570
-                    $bY+= $border['t']['width'];
1571
-                }
1572
-                if ($border['r']['width']) {
1573
-                    $bW-= $border['r']['width'];
1574
-                }
1575
-
1576
-                // get the size of the image
1577
-                // WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
1578
-                $imageInfos=@getimagesize($iName);
1579
-
1580
-                // if the image can not be loaded
1581
-                if (count($imageInfos)<2) {
1582
-                    if ($this->_testIsImage) {
1583
-                        throw new HTML2PDF_exception(6, $iName);
1584
-                    }
1585
-                } else {
1586
-                    // convert the size of the image from pixel to the unit of the PDF
1587
-                    $imageWidth    = 72./96.*$imageInfos[0]/$this->pdf->getK();
1588
-                    $imageHeight    = 72./96.*$imageInfos[1]/$this->pdf->getK();
1589
-
1590
-                    // prepare the position of the backgroung
1591
-                    if ($iRepeat[0]) $iPosition[0] = $bX;
1592
-                    else if (preg_match('/^([-]?[0-9\.]+)%/isU', $iPosition[0], $match)) $iPosition[0] = $bX + $match[1]*($bW-$imageWidth)/100;
1593
-                    else $iPosition[0] = $bX+$iPosition[0];
1594
-
1595
-                    if ($iRepeat[1]) $iPosition[1] = $bY;
1596
-                    else if (preg_match('/^([-]?[0-9\.]+)%/isU', $iPosition[1], $match)) $iPosition[1] = $bY + $match[1]*($bH-$imageHeight)/100;
1597
-                    else $iPosition[1] = $bY+$iPosition[1];
1598
-
1599
-                    $imageXmin = $bX;
1600
-                    $imageXmax = $bX+$bW;
1601
-                    $imageYmin = $bY;
1602
-                    $imageYmax = $bY+$bH;
1603
-
1604
-                    if (!$iRepeat[0] && !$iRepeat[1]) {
1605
-                        $imageXmin =     $iPosition[0]; $imageXmax =     $iPosition[0]+$imageWidth;
1606
-                        $imageYmin =     $iPosition[1]; $imageYmax =     $iPosition[1]+$imageHeight;
1607
-                    } else if ($iRepeat[0] && !$iRepeat[1]) {
1608
-                        $imageYmin =     $iPosition[1]; $imageYmax =     $iPosition[1]+$imageHeight;
1609
-                    } else if (!$iRepeat[0] && $iRepeat[1]) {
1610
-                        $imageXmin =     $iPosition[0]; $imageXmax =     $iPosition[0]+$imageWidth;
1611
-                    }
1612
-
1613
-                    // build the path to display the image (because of radius)
1614
-                    $this->pdf->clippingPathStart($bX, $bY, $bW, $bH, $inTL, $inTR, $inBL, $inBR);
1615
-
1616
-                    // repeat the image
1617
-                    for ($iY=$imageYmin; $iY<$imageYmax; $iY+=$imageHeight) {
1618
-                        for ($iX=$imageXmin; $iX<$imageXmax; $iX+=$imageWidth) {
1619
-                            $cX = null;
1620
-                            $cY = null;
1621
-                            $cW = $imageWidth;
1622
-                            $cH = $imageHeight;
1623
-                            if ($imageYmax-$iY<$imageHeight) {
1624
-                                $cX = $iX;
1625
-                                $cY = $iY;
1626
-                                $cH = $imageYmax-$iY;
1627
-                            }
1628
-                            if ($imageXmax-$iX<$imageWidth) {
1629
-                                $cX = $iX;
1630
-                                $cY = $iY;
1631
-                                $cW = $imageXmax-$iX;
1632
-                            }
1633
-
1634
-                            $this->pdf->Image($iName, $iX, $iY, $imageWidth, $imageHeight, '', '');
1635
-                        }
1636
-                    }
1637
-
1638
-                    // end of the path
1639
-                    $this->pdf->clippingPathStop();
1640
-                }
1641
-            }
1642
-
1643
-            // adding some loose (0.01mm)
1644
-            $loose = 0.01;
1645
-            $x-= $loose;
1646
-            $y-= $loose;
1647
-            $w+= 2.*$loose;
1648
-            $h+= 2.*$loose;
1649
-            if ($border['l']['width']) $border['l']['width']+= 2.*$loose;
1650
-            if ($border['t']['width']) $border['t']['width']+= 2.*$loose;
1651
-            if ($border['r']['width']) $border['r']['width']+= 2.*$loose;
1652
-            if ($border['b']['width']) $border['b']['width']+= 2.*$loose;
1653
-
1654
-            // prepare the test on borders
1655
-            $testBl = ($border['l']['width'] && $border['l']['color'][0]!==null);
1656
-            $testBt = ($border['t']['width'] && $border['t']['color'][0]!==null);
1657
-            $testBr = ($border['r']['width'] && $border['r']['color'][0]!==null);
1658
-            $testBb = ($border['b']['width'] && $border['b']['color'][0]!==null);
1659
-
1660
-            // draw the radius bottom-left
1661
-            if (is_array($outBL) && ($testBb || $testBl)) {
1662
-                if ($inBL) {
1663
-                    $courbe = array();
1664
-                    $courbe[] = $x+$outBL[0];              $courbe[] = $y+$h;
1665
-                    $courbe[] = $x;                        $courbe[] = $y+$h-$outBL[1];
1666
-                    $courbe[] = $x+$outBL[0];              $courbe[] = $y+$h-$border['b']['width'];
1667
-                    $courbe[] = $x+$border['l']['width'];  $courbe[] = $y+$h-$outBL[1];
1668
-                    $courbe[] = $x+$outBL[0];              $courbe[] = $y+$h-$outBL[1];
1669
-                } else {
1670
-                    $courbe = array();
1671
-                    $courbe[] = $x+$outBL[0];              $courbe[] = $y+$h;
1672
-                    $courbe[] = $x;                        $courbe[] = $y+$h-$outBL[1];
1673
-                    $courbe[] = $x+$border['l']['width'];  $courbe[] = $y+$h-$border['b']['width'];
1674
-                    $courbe[] = $x+$outBL[0];              $courbe[] = $y+$h-$outBL[1];
1675
-                }
1676
-                $this->_drawCurve($courbe, $border['l']['color']);
1677
-            }
1678
-
1679
-            // draw the radius left-top
1680
-            if (is_array($outTL) && ($testBt || $testBl)) {
1681
-                if ($inTL) {
1682
-                    $courbe = array();
1683
-                    $courbe[] = $x;                        $courbe[] = $y+$outTL[1];
1684
-                    $courbe[] = $x+$outTL[0];              $courbe[] = $y;
1685
-                    $courbe[] = $x+$border['l']['width'];  $courbe[] = $y+$outTL[1];
1686
-                    $courbe[] = $x+$outTL[0];              $courbe[] = $y+$border['t']['width'];
1687
-                    $courbe[] = $x+$outTL[0];              $courbe[] = $y+$outTL[1];
1688
-                } else {
1689
-                    $courbe = array();
1690
-                    $courbe[] = $x;                        $courbe[] = $y+$outTL[1];
1691
-                    $courbe[] = $x+$outTL[0];              $courbe[] = $y;
1692
-                    $courbe[] = $x+$border['l']['width'];  $courbe[] = $y+$border['t']['width'];
1693
-                    $courbe[] = $x+$outTL[0];              $courbe[] = $y+$outTL[1];
1694
-                }
1695
-                $this->_drawCurve($courbe, $border['t']['color']);
1696
-            }
1697
-
1698
-            // draw the radius top-right
1699
-            if (is_array($outTR) && ($testBt || $testBr)) {
1700
-                if ($inTR) {
1701
-                    $courbe = array();
1702
-                    $courbe[] = $x+$w-$outTR[0];             $courbe[] = $y;
1703
-                    $courbe[] = $x+$w;                       $courbe[] = $y+$outTR[1];
1704
-                    $courbe[] = $x+$w-$outTR[0];             $courbe[] = $y+$border['t']['width'];
1705
-                    $courbe[] = $x+$w-$border['r']['width']; $courbe[] = $y+$outTR[1];
1706
-                    $courbe[] = $x+$w-$outTR[0];             $courbe[] = $y+$outTR[1];
1707
-                } else {
1708
-                    $courbe = array();
1709
-                    $courbe[] = $x+$w-$outTR[0];             $courbe[] = $y;
1710
-                    $courbe[] = $x+$w;                       $courbe[] = $y+$outTR[1];
1711
-                    $courbe[] = $x+$w-$border['r']['width']; $courbe[] = $y+$border['t']['width'];
1712
-                    $courbe[] = $x+$w-$outTR[0];             $courbe[] = $y+$outTR[1];
1713
-                }
1714
-                $this->_drawCurve($courbe, $border['r']['color']);
1715
-            }
1716
-
1717
-            // draw the radius right-bottom
1718
-            if (is_array($outBR) && ($testBb || $testBr)) {
1719
-                if ($inBR) {
1720
-                    $courbe = array();
1721
-                    $courbe[] = $x+$w;                       $courbe[] = $y+$h-$outBR[1];
1722
-                    $courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h;
1723
-                    $courbe[] = $x+$w-$border['r']['width']; $courbe[] = $y+$h-$outBR[1];
1724
-                    $courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h-$border['b']['width'];
1725
-                    $courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h-$outBR[1];
1726
-                } else {
1727
-                    $courbe = array();
1728
-                    $courbe[] = $x+$w;                       $courbe[] = $y+$h-$outBR[1];
1729
-                    $courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h;
1730
-                    $courbe[] = $x+$w-$border['r']['width']; $courbe[] = $y+$h-$border['b']['width'];
1731
-                    $courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h-$outBR[1];
1732
-                }
1733
-                $this->_drawCurve($courbe, $border['b']['color']);
1734
-            }
1735
-
1736
-            // draw the left border
1737
-            if ($testBl) {
1738
-                $pt = array();
1739
-                $pt[] = $x;                       $pt[] = $y+$h;
1740
-                $pt[] = $x;                       $pt[] = $y+$h-$border['b']['width'];
1741
-                $pt[] = $x;                       $pt[] = $y+$border['t']['width'];
1742
-                $pt[] = $x;                       $pt[] = $y;
1743
-                $pt[] = $x+$border['l']['width']; $pt[] = $y+$border['t']['width'];
1744
-                $pt[] = $x+$border['l']['width']; $pt[] = $y+$h-$border['b']['width'];
1745
-
1746
-                $bord = 3;
1747
-                if (is_array($outBL)) {
1748
-                    $bord-=1;
1749
-                    $pt[3] -= $outBL[1] - $border['b']['width'];
1750
-                    if ($inBL) $pt[11]-= $inBL[1];
1751
-                    unset($pt[0]);unset($pt[1]);
1752
-                }
1753
-                if (is_array($outTL)) {
1754
-                    $bord-=2;
1755
-                    $pt[5] += $outTL[1]-$border['t']['width'];
1756
-                    if ($inTL) $pt[9] += $inTL[1];
1757
-                    unset($pt[6]);unset($pt[7]);
1758
-                }
1759
-
1760
-                $pt = array_values($pt);
1761
-                $this->_drawLine($pt, $border['l']['color'], $border['l']['type'], $border['l']['width'], $bord);
1762
-            }
1763
-
1764
-            // draw the top border
1765
-            if ($testBt) {
1766
-                $pt = array();
1767
-                $pt[] = $x;                          $pt[] = $y;
1768
-                $pt[] = $x+$border['l']['width'];    $pt[] = $y;
1769
-                $pt[] = $x+$w-$border['r']['width']; $pt[] = $y;
1770
-                $pt[] = $x+$w;                       $pt[] = $y;
1771
-                $pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$border['t']['width'];
1772
-                $pt[] = $x+$border['l']['width'];    $pt[] = $y+$border['t']['width'];
1773
-
1774
-                $bord = 3;
1775
-                if (is_array($outTL)) {
1776
-                    $bord-=1;
1777
-                    $pt[2] += $outTL[0] - $border['l']['width'];
1778
-                    if ($inTL) $pt[10]+= $inTL[0];
1779
-                    unset($pt[0]);unset($pt[1]);
1780
-                }
1781
-                if (is_array($outTR)) {
1782
-                    $bord-=2;
1783
-                    $pt[4] -= $outTR[0] - $border['r']['width'];
1784
-                    if ($inTR) $pt[8] -= $inTR[0];
1785
-                    unset($pt[6]);unset($pt[7]);
1786
-                }
1787
-
1788
-                $pt = array_values($pt);
1789
-                $this->_drawLine($pt, $border['t']['color'], $border['t']['type'], $border['t']['width'], $bord);
1790
-            }
1791
-
1792
-            // draw the right border
1793
-            if ($testBr) {
1794
-                $pt = array();
1795
-                $pt[] = $x+$w;                       $pt[] = $y;
1796
-                $pt[] = $x+$w;                       $pt[] = $y+$border['t']['width'];
1797
-                $pt[] = $x+$w;                       $pt[] = $y+$h-$border['b']['width'];
1798
-                $pt[] = $x+$w;                       $pt[] = $y+$h;
1799
-                $pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$h-$border['b']['width'];
1800
-                $pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$border['t']['width'];
1801
-
1802
-                $bord = 3;
1803
-                if (is_array($outTR)) {
1804
-                    $bord-=1;
1805
-                    $pt[3] += $outTR[1] - $border['t']['width'];
1806
-                    if ($inTR) $pt[11]+= $inTR[1];
1807
-                    unset($pt[0]);unset($pt[1]);
1808
-                }
1809
-                if (is_array($outBR)) {
1810
-                    $bord-=2;
1811
-                    $pt[5] -= $outBR[1] - $border['b']['width'];
1812
-                    if ($inBR) $pt[9] -= $inBR[1];
1813
-                    unset($pt[6]);unset($pt[7]);
1814
-                }
1815
-
1816
-                $pt = array_values($pt);
1817
-                $this->_drawLine($pt, $border['r']['color'], $border['r']['type'], $border['r']['width'], $bord);
1818
-            }
1819
-
1820
-            // draw the bottom border
1821
-            if ($testBb) {
1822
-                $pt = array();
1823
-                $pt[] = $x+$w;                       $pt[] = $y+$h;
1824
-                $pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$h;
1825
-                $pt[] = $x+$border['l']['width'];    $pt[] = $y+$h;
1826
-                $pt[] = $x;                          $pt[] = $y+$h;
1827
-                $pt[] = $x+$border['l']['width'];    $pt[] = $y+$h-$border['b']['width'];
1828
-                $pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$h-$border['b']['width'];
1829
-
1830
-                $bord = 3;
1831
-                if (is_array($outBL)) {
1832
-                    $bord-=2;
1833
-                    $pt[4] += $outBL[0] - $border['l']['width'];
1834
-                    if ($inBL) $pt[8] += $inBL[0];
1835
-                    unset($pt[6]);unset($pt[7]);
1836
-                }
1837
-                if (is_array($outBR)) {
1838
-                    $bord-=1;
1839
-                    $pt[2] -= $outBR[0] - $border['r']['width'];
1840
-                    if ($inBR) $pt[10]-= $inBR[0];
1841
-                    unset($pt[0]);unset($pt[1]);
1842
-
1843
-                }
1844
-
1845
-                $pt = array_values($pt);
1846
-                $this->_drawLine($pt, $border['b']['color'], $border['b']['type'], $border['b']['width'], $bord);
1847
-            }
1848
-
1849
-            if ($background['color']) {
1850
-                $this->pdf->setFillColorArray($background['color']);
1851
-            }
1852
-
1853
-            return true;
1854
-        }
1855
-
1856
-        /**
1857
-         * draw a curve (for border radius)
1858
-         *
1859
-         * @access protected
1860
-         * @param  array $pt
1861
-         * @param  array $color
1862
-         */
1863
-        protected function _drawCurve($pt, $color)
1864
-        {
1865
-            $this->pdf->setFillColorArray($color);
1866
-
1867
-            if (count($pt)==10)
1868
-                $this->pdf->drawCurve($pt[0], $pt[1], $pt[2], $pt[3], $pt[4], $pt[5], $pt[6], $pt[7], $pt[8], $pt[9]);
1869
-            else
1870
-                $this->pdf->drawCorner($pt[0], $pt[1], $pt[2], $pt[3], $pt[4], $pt[5], $pt[6], $pt[7]);
1871
-        }
1872
-
1873
-        /**
1874
-         * draw a ligne with a specific type, and specific start and end for radius
1875
-         *
1876
-         * @access protected
1877
-         * @param  array   $pt
1878
-         * @param  float   $color
1879
-         * @param  string  $type (dashed, dotted, double, solid)
1880
-         * @param  float   $width
1881
-         * @param  integer $radius (binary from 0 to 3 with 1=>start with a radius, 2=>end with a radius)
1882
-         */
1883
-        protected function _drawLine($pt, $color, $type, $width, $radius=3)
1884
-        {
1885
-            // set the fill color
1886
-            $this->pdf->setFillColorArray($color);
1887
-
1888
-            // if dashed or dotted
1889
-            if ($type=='dashed' || $type=='dotted') {
1890
-
1891
-                // clean the end of the line, if radius
1892
-                if ($radius==1) {
1893
-                    $tmp = array(); $tmp[]=$pt[0]; $tmp[]=$pt[1]; $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[8]; $tmp[]=$pt[9];
1894
-                    $this->pdf->Polygon($tmp, 'F');
1895
-
1896
-                    $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];
1897
-                    $pt = $tmp;
1898
-                } else if ($radius==2) {
1899
-                    $tmp = array(); $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[4]; $tmp[]=$pt[5]; $tmp[]=$pt[6]; $tmp[]=$pt[7];
1900
-                    $this->pdf->Polygon($tmp, 'F');
1901
-
1902
-                    $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];
1903
-                    $pt = $tmp;
1904
-                } else if ($radius==3) {
1905
-                    $tmp = array(); $tmp[]=$pt[0]; $tmp[]=$pt[1]; $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[10]; $tmp[]=$pt[11];
1906
-                    $this->pdf->Polygon($tmp, 'F');
1907
-
1908
-                    $tmp = array(); $tmp[]=$pt[4]; $tmp[]=$pt[5]; $tmp[]=$pt[6]; $tmp[]=$pt[7]; $tmp[]=$pt[8]; $tmp[]=$pt[9];
1909
-                    $this->pdf->Polygon($tmp, 'F');
1910
-
1911
-                    $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];
1912
-                    $pt = $tmp;
1913
-                }
1914
-
1915
-                // horisontal or vertical line
1916
-                if ($pt[2]==$pt[0]) {
1917
-                    $l = abs(($pt[3]-$pt[1])*0.5);
1918
-                    $px = 0;
1919
-                    $py = $width;
1920
-                    $x1 = $pt[0]; $y1 = ($pt[3]+$pt[1])*0.5;
1921
-                    $x2 = $pt[6]; $y2 = ($pt[7]+$pt[5])*0.5;
1922
-                } else {
1923
-                    $l = abs(($pt[2]-$pt[0])*0.5);
1924
-                    $px = $width;
1925
-                    $py = 0;
1926
-                    $x1 = ($pt[2]+$pt[0])*0.5; $y1 = $pt[1];
1927
-                    $x2 = ($pt[6]+$pt[4])*0.5; $y2 = $pt[7];
1928
-                }
1929
-
1930
-                // if dashed : 3x bigger than dotted
1931
-                if ($type=='dashed') {
1932
-                    $px = $px*3.;
1933
-                    $py = $py*3.;
1934
-                }
1935
-                $mode = ($l/($px+$py)<.5);
1936
-
1937
-                // display the dotted/dashed line
1938
-                for ($i=0; $l-($px+$py)*($i-0.5)>0; $i++) {
1939
-                    if (($i%2)==$mode) {
1940
-                        $j = $i-0.5;
1941
-                        $lx1 = $px*($j);   if ($lx1<-$l) $lx1 =-$l;
1942
-                        $ly1 = $py*($j);   if ($ly1<-$l) $ly1 =-$l;
1943
-                        $lx2 = $px*($j+1); if ($lx2>$l)  $lx2 = $l;
1944
-                        $ly2 = $py*($j+1); if ($ly2>$l)  $ly2 = $l;
1945
-
1946
-                        $tmp = array();
1947
-                        $tmp[] = $x1+$lx1; $tmp[] = $y1+$ly1;
1948
-                        $tmp[] = $x1+$lx2; $tmp[] = $y1+$ly2;
1949
-                        $tmp[] = $x2+$lx2; $tmp[] = $y2+$ly2;
1950
-                        $tmp[] = $x2+$lx1; $tmp[] = $y2+$ly1;
1951
-                        $this->pdf->Polygon($tmp, 'F');
1952
-
1953
-                        if ($j>0) {
1954
-                            $tmp = array();
1955
-                            $tmp[] = $x1-$lx1; $tmp[] = $y1-$ly1;
1956
-                            $tmp[] = $x1-$lx2; $tmp[] = $y1-$ly2;
1957
-                            $tmp[] = $x2-$lx2; $tmp[] = $y2-$ly2;
1958
-                            $tmp[] = $x2-$lx1; $tmp[] = $y2-$ly1;
1959
-                            $this->pdf->Polygon($tmp, 'F');
1960
-                        }
1961
-                    }
1962
-                }
1963
-            } else if ($type=='double') {
1964
-
1965
-                // if double, 2 lines : 0=>1/3 and 2/3=>1
1966
-                $pt1 = $pt;
1967
-                $pt2 = $pt;
1968
-
1969
-                if (count($pt)==12) {
1970
-                    // line 1
1971
-                    $pt1[0] = ($pt[0]-$pt[10])*0.33 + $pt[10];
1972
-                    $pt1[1] = ($pt[1]-$pt[11])*0.33 + $pt[11];
1973
-                    $pt1[2] = ($pt[2]-$pt[10])*0.33 + $pt[10];
1974
-                    $pt1[3] = ($pt[3]-$pt[11])*0.33 + $pt[11];
1975
-                    $pt1[4] = ($pt[4]-$pt[8])*0.33 + $pt[8];
1976
-                    $pt1[5] = ($pt[5]-$pt[9])*0.33 + $pt[9];
1977
-                    $pt1[6] = ($pt[6]-$pt[8])*0.33 + $pt[8];
1978
-                    $pt1[7] = ($pt[7]-$pt[9])*0.33 + $pt[9];
1979
-                    $pt2[10]= ($pt[10]-$pt[0])*0.33 + $pt[0];
1980
-                    $pt2[11]= ($pt[11]-$pt[1])*0.33 + $pt[1];
1981
-
1982
-                    // line 2
1983
-                    $pt2[2] = ($pt[2] -$pt[0])*0.33 + $pt[0];
1984
-                    $pt2[3] = ($pt[3] -$pt[1])*0.33 + $pt[1];
1985
-                    $pt2[4] = ($pt[4] -$pt[6])*0.33 + $pt[6];
1986
-                    $pt2[5] = ($pt[5] -$pt[7])*0.33 + $pt[7];
1987
-                    $pt2[8] = ($pt[8] -$pt[6])*0.33 + $pt[6];
1988
-                    $pt2[9] = ($pt[9] -$pt[7])*0.33 + $pt[7];
1989
-                } else {
1990
-                    // line 1
1991
-                    $pt1[0] = ($pt[0]-$pt[6])*0.33 + $pt[6];
1992
-                    $pt1[1] = ($pt[1]-$pt[7])*0.33 + $pt[7];
1993
-                    $pt1[2] = ($pt[2]-$pt[4])*0.33 + $pt[4];
1994
-                    $pt1[3] = ($pt[3]-$pt[5])*0.33 + $pt[5];
1995
-
1996
-                    // line 2
1997
-                    $pt2[6] = ($pt[6]-$pt[0])*0.33 + $pt[0];
1998
-                    $pt2[7] = ($pt[7]-$pt[1])*0.33 + $pt[1];
1999
-                    $pt2[4] = ($pt[4]-$pt[2])*0.33 + $pt[2];
2000
-                    $pt2[5] = ($pt[5]-$pt[3])*0.33 + $pt[3];
2001
-                }
2002
-                $this->pdf->Polygon($pt1, 'F');
2003
-                $this->pdf->Polygon($pt2, 'F');
2004
-            } else if ($type=='solid') {
2005
-                // solid line : draw directly the polygon
2006
-                $this->pdf->Polygon($pt, 'F');
2007
-            }
2008
-        }
2009
-
2010
-        /**
2011
-         * prepare a transform matrix, only for drawing a SVG graphic
2012
-         *
2013
-         * @access protected
2014
-         * @param  string $transform
2015
-         * @return array  $matrix
2016
-         */
2017
-        protected function _prepareTransform($transform)
2018
-        {
2019
-            // it can not be  empty
2020
-            if (!$transform) return null;
2021
-
2022
-            // sctions must be like scale(...)
2023
-            if (!preg_match_all('/([a-z]+)\(([^\)]*)\)/isU', $transform, $match)) return null;
2024
-
2025
-            // prepare the list of the actions
2026
-            $actions = array();
2027
-
2028
-            // for actions
2029
-            for ($k=0; $k<count($match[0]); $k++) {
2030
-
2031
-                // get the name of the action
2032
-                $name = strtolower($match[1][$k]);
2033
-
2034
-                // get the parameters of the action
2035
-                $val = explode(',', trim($match[2][$k]));
2036
-                foreach ($val as $i => $j) {
2037
-                    $val[$i] = trim($j);
2038
-                }
2039
-
2040
-                // prepare the matrix, depending on the action
2041
-                switch($name)
2042
-                {
2043
-                    case 'scale':
2044
-                        if (!isset($val[0])) $val[0] = 1.;      else $val[0] = 1.*$val[0];
2045
-                        if (!isset($val[1])) $val[1] = $val[0]; else $val[1] = 1.*$val[1];
2046
-                        $actions[] = array($val[0],0,0,$val[1],0,0);
2047
-                        break;
2048
-
2049
-                    case 'translate':
2050
-                        if (!isset($val[0])) $val[0] = 0.; else $val[0] = $this->parsingCss->ConvertToMM($val[0], $this->_isInDraw['w']);
2051
-                        if (!isset($val[1])) $val[1] = 0.; else $val[1] = $this->parsingCss->ConvertToMM($val[1], $this->_isInDraw['h']);
2052
-                        $actions[] = array(1,0,0,1,$val[0],$val[1]);
2053
-                        break;
2054
-
2055
-                    case 'rotate':
2056
-                        if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*M_PI/180.;
2057
-                        if (!isset($val[1])) $val[1] = 0.; else $val[1] = $this->parsingCss->ConvertToMM($val[1], $this->_isInDraw['w']);
2058
-                        if (!isset($val[2])) $val[2] = 0.; else $val[2] = $this->parsingCss->ConvertToMM($val[2], $this->_isInDraw['h']);
2059
-                        if ($val[1] || $val[2]) $actions[] = array(1,0,0,1,-$val[1],-$val[2]);
2060
-                        $actions[] = array(cos($val[0]),sin($val[0]),-sin($val[0]),cos($val[0]),0,0);
2061
-                        if ($val[1] || $val[2]) $actions[] = array(1,0,0,1,$val[1],$val[2]);
2062
-                        break;
2063
-
2064
-                    case 'skewx':
2065
-                        if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*M_PI/180.;
2066
-                        $actions[] = array(1,0,tan($val[0]),1,0,0);
2067
-                        break;
2068
-
2069
-                    case 'skewy':
2070
-                        if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*M_PI/180.;
2071
-                        $actions[] = array(1,tan($val[0]),0,1,0,0);
2072
-                        break;
2073
-                    case 'matrix':
2074
-                        if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*1.;
2075
-                        if (!isset($val[1])) $val[1] = 0.; else $val[1] = $val[1]*1.;
2076
-                        if (!isset($val[2])) $val[2] = 0.; else $val[2] = $val[2]*1.;
2077
-                        if (!isset($val[3])) $val[3] = 0.; else $val[3] = $val[3]*1.;
2078
-                        if (!isset($val[4])) $val[4] = 0.; else $val[4] = $this->parsingCss->ConvertToMM($val[4], $this->_isInDraw['w']);
2079
-                        if (!isset($val[5])) $val[5] = 0.; else $val[5] = $this->parsingCss->ConvertToMM($val[5], $this->_isInDraw['h']);
2080
-                        $actions[] =$val;
2081
-                        break;
2082
-                }
2083
-            }
2084
-
2085
-            // if ther is no actions => return
2086
-            if (!$actions) return null;
2087
-
2088
-            // get the first matrix
2089
-            $m = $actions[0]; unset($actions[0]);
2090
-
2091
-            // foreach matrix => multiply to the last matrix
2092
-            foreach ($actions as $n) {
2093
-                $m = array(
2094
-                    $m[0]*$n[0]+$m[2]*$n[1],
2095
-                    $m[1]*$n[0]+$m[3]*$n[1],
2096
-                    $m[0]*$n[2]+$m[2]*$n[3],
2097
-                    $m[1]*$n[2]+$m[3]*$n[3],
2098
-                    $m[0]*$n[4]+$m[2]*$n[5]+$m[4],
2099
-                    $m[1]*$n[4]+$m[3]*$n[5]+$m[5]
2100
-                );
2101
-            }
2102
-
2103
-            // return the matrix
2104
-            return $m;
2105
-        }
2106
-
2107
-        /**
2108
-         * @access protected
2109
-         * @param  &array $cases
2110
-         * @param  &array $corr
2111
-         */
2112
-        protected function _calculateTableCellSize(&$cases, &$corr)
2113
-        {
2114
-            if (!isset($corr[0])) return true;
2115
-
2116
-            // for each cell without colspan, we get the max width for each column
2117
-            $sw = array();
2118
-            for ($x=0; $x<count($corr[0]); $x++) {
2119
-                $m=0;
2120
-                for ($y=0; $y<count($corr); $y++) {
2121
-                    if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][2]==1) {
2122
-                        $m = max($m, $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w']);
2123
-                    }
2124
-                }
2125
-                $sw[$x] = $m;
2126
-            }
2127
-
2128
-            // for each cell with colspan, we adapt the width of each column
2129
-            for ($x=0; $x<count($corr[0]); $x++) {
2130
-                for ($y=0; $y<count($corr); $y++) {
2131
-                    if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][2]>1) {
2132
-
2133
-                        // sum the max width of each column in colspan
2134
-                        $s = 0; for ($i=0; $i<$corr[$y][$x][2]; $i++) $s+= $sw[$x+$i];
2135
-
2136
-                        // if the max width is < the width of the cell with colspan => we adapt the width of each max width
2137
-                        if ($s>0 && $s<$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w']) {
2138
-                            for ($i=0; $i<$corr[$y][$x][2]; $i++) {
2139
-                                $sw[$x+$i] = $sw[$x+$i]/$s*$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'];
2140
-                            }
2141
-                        }
2142
-                    }
2143
-                }
2144
-            }
2145
-
2146
-            // set the new width, for each cell
2147
-            for ($x=0; $x<count($corr[0]); $x++) {
2148
-                for ($y=0; $y<count($corr); $y++) {
2149
-                    if (isset($corr[$y][$x]) && is_array($corr[$y][$x])) {
2150
-                        // without colspan
2151
-                        if ($corr[$y][$x][2]==1) {
2152
-                            $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'] = $sw[$x];
2153
-                        // with colspan
2154
-                        } else {
2155
-                            $s = 0;
2156
-                            for ($i=0; $i<$corr[$y][$x][2]; $i++) {
2157
-                                $s+= $sw[$x+$i];
2158
-                            }
2159
-                            $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'] = $s;
2160
-                        }
2161
-                    }
2162
-                }
2163
-            }
2164
-
2165
-            // for each cell without rowspan, we get the max height for each line
2166
-            $sh = array();
2167
-            for ($y=0; $y<count($corr); $y++) {
2168
-                $m=0;
2169
-                for ($x=0; $x<count($corr[0]); $x++) {
2170
-                    if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][3]==1) {
2171
-                        $m = max($m, $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h']);
2172
-                    }
2173
-                }
2174
-                $sh[$y] = $m;
2175
-            }
2176
-
2177
-            // for each cell with rowspan, we adapt the height of each line
2178
-            for ($y=0; $y<count($corr); $y++) {
2179
-                for ($x=0; $x<count($corr[0]); $x++) {
2180
-                    if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][3]>1) {
2181
-
2182
-                        // sum the max height of each line in rowspan
2183
-                        $s = 0; for ($i=0; $i<$corr[$y][$x][3]; $i++) $s+= $sh[$y+$i];
2184
-
2185
-                        // if the max height is < the height of the cell with rowspan => we adapt the height of each max height
2186
-                        if ($s>0 && $s<$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h']) {
2187
-                            for ($i=0; $i<$corr[$y][$x][3]; $i++) {
2188
-                                $sh[$y+$i] = $sh[$y+$i]/$s*$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h'];
2189
-                            }
2190
-                        }
2191
-                    }
2192
-                }
2193
-            }
2194
-
2195
-            // set the new height, for each cell
2196
-            for ($y=0; $y<count($corr); $y++) {
2197
-                for ($x=0; $x<count($corr[0]); $x++) {
2198
-                    if (isset($corr[$y][$x]) && is_array($corr[$y][$x])) {
2199
-                        // without rowspan
2200
-                        if ($corr[$y][$x][3]==1) {
2201
-                            $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h'] = $sh[$y];
2202
-                        // with rowspan
2203
-                        } else {
2204
-                            $s = 0;
2205
-                            for ($i=0; $i<$corr[$y][$x][3]; $i++) {
2206
-                                $s+= $sh[$y+$i];
2207
-                            }
2208
-                            $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h'] = $s;
2209
-
2210
-                            for ($j=1; $j<$corr[$y][$x][3]; $j++) {
2211
-                                $tx = $x+1;
2212
-                                $ty = $y+$j;
2213
-                                for (true; isset($corr[$ty][$tx]) && !is_array($corr[$ty][$tx]); $tx++);
2214
-                                if (isset($corr[$ty][$tx])) {
2215
-                                    $cases[$corr[$ty][$tx][1]][$corr[$ty][$tx][0]]['dw']+= $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'];
2216
-                                }
2217
-                            }
2218
-                        }
2219
-                    }
2220
-                }
2221
-            }
2222
-        }
2223
-
2224
-        /**
2225
-         * tag : PAGE
2226
-         * mode : OPEN
2227
-         *
2228
-         * @param  array $param
2229
-         * @return boolean
2230
-         */
2231
-        protected function _tag_open_PAGE($param)
2232
-        {
2233
-            if ($this->_isForOneLine) return false;
2234
-            if ($this->_debugActif) $this->_DEBUG_add('PAGE '.($this->_page+1), true);
2235
-
2236
-            $newPageSet= (!isset($param['pageset']) || $param['pageset']!='old');
2237
-
2238
-            $resetPageNumber = (isset($param['pagegroup']) && $param['pagegroup']=='new');
2239
-
2240
-            $this->_maxH = 0;
2241
-
2242
-            // if new page set asked
2243
-            if ($newPageSet) {
2244
-                $this->_subHEADER = array();
2245
-                $this->_subFOOTER = array();
2246
-
2247
-                // orientation
2248
-                $orientation = '';
2249
-                if (isset($param['orientation'])) {
2250
-                    $param['orientation'] = strtolower($param['orientation']);
2251
-                    if ($param['orientation']=='p')         $orientation = 'P';
2252
-                    if ($param['orientation']=='portrait')  $orientation = 'P';
2253
-
2254
-                    if ($param['orientation']=='l')         $orientation = 'L';
2255
-                    if ($param['orientation']=='paysage')   $orientation = 'L';
2256
-                    if ($param['orientation']=='landscape') $orientation = 'L';
2257
-                }
2258
-
2259
-                // format
2260
-                $format = null;
2261
-                if (isset($param['format'])) {
2262
-                    $format = strtolower($param['format']);
2263
-                    if (preg_match('/^([0-9]+)x([0-9]+)$/isU', $format, $match)) {
2264
-                        $format = array(intval($match[1]), intval($match[2]));
2265
-                    }
2266
-                }
2267
-
2268
-                // background
2269
-                $background = array();
2270
-                if (isset($param['backimg'])) {
2271
-                    $background['img']    = isset($param['backimg'])  ? $param['backimg']  : '';       // src of the image
2272
-                    $background['posX']   = isset($param['backimgx']) ? $param['backimgx'] : 'center'; // horizontale position of the image
2273
-                    $background['posY']   = isset($param['backimgy']) ? $param['backimgy'] : 'middle'; // vertical position of the image
2274
-                    $background['width']  = isset($param['backimgw']) ? $param['backimgw'] : '100%';   // width of the image (100% = page width)
2275
-
2276
-                    // convert the src of the image, if parameters
2277
-                    $background['img'] = str_replace('&amp;', '&', $background['img']);
2278
-
2279
-                    // convert the positions
2280
-                    if ($background['posX']=='left')    $background['posX'] = '0%';
2281
-                    if ($background['posX']=='center')  $background['posX'] = '50%';
2282
-                    if ($background['posX']=='right')   $background['posX'] = '100%';
2283
-                    if ($background['posY']=='top')     $background['posY'] = '0%';
2284
-                    if ($background['posY']=='middle')  $background['posY'] = '50%';
2285
-                    if ($background['posY']=='bottom')  $background['posY'] = '100%';
2286
-
2287
-                    if ($background['img']) {
2288
-                        // get the size of the image
2289
-                        // WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
2290
-                        $infos=@getimagesize($background['img']);
2291
-                        if (count($infos)>1) {
2292
-                            $imageWidth = $this->parsingCss->ConvertToMM($background['width'], $this->pdf->getW());
2293
-                            $imageHeight = $imageWidth*$infos[1]/$infos[0];
2294
-
2295
-                            $background['width'] = $imageWidth;
2296
-                            $background['posX']  = $this->parsingCss->ConvertToMM($background['posX'], $this->pdf->getW() - $imageWidth);
2297
-                            $background['posY']  = $this->parsingCss->ConvertToMM($background['posY'], $this->pdf->getH() - $imageHeight);
2298
-                        } else {
2299
-                            $background = array();
2300
-                        }
2301
-                    } else {
2302
-                        $background = array();
2303
-                    }
2304
-                }
2305
-
2306
-                // margins of the page
2307
-                $background['top']    = isset($param['backtop'])    ? $param['backtop']    : '0';
2308
-                $background['bottom'] = isset($param['backbottom']) ? $param['backbottom'] : '0';
2309
-                $background['left']   = isset($param['backleft'])   ? $param['backleft']   : '0';
2310
-                $background['right']  = isset($param['backright'])  ? $param['backright']  : '0';
2311
-
2312
-                // if no unit => mm
2313
-                if (preg_match('/^([0-9]*)$/isU', $background['top']))    $background['top']    .= 'mm';
2314
-                if (preg_match('/^([0-9]*)$/isU', $background['bottom'])) $background['bottom'] .= 'mm';
2315
-                if (preg_match('/^([0-9]*)$/isU', $background['left']))   $background['left']   .= 'mm';
2316
-                if (preg_match('/^([0-9]*)$/isU', $background['right']))  $background['right']  .= 'mm';
2317
-
2318
-                // convert to mm
2319
-                $background['top']    = $this->parsingCss->ConvertToMM($background['top'], $this->pdf->getH());
2320
-                $background['bottom'] = $this->parsingCss->ConvertToMM($background['bottom'], $this->pdf->getH());
2321
-                $background['left']   = $this->parsingCss->ConvertToMM($background['left'], $this->pdf->getW());
2322
-                $background['right']  = $this->parsingCss->ConvertToMM($background['right'], $this->pdf->getW());
2323
-
2324
-                // get the background color
2325
-                $res = false;
2326
-                $background['color']    = isset($param['backcolor'])    ? $this->parsingCss->convertToColor($param['backcolor'], $res) : null;
2327
-                if (!$res) $background['color'] = null;
2328
-
2329
-                $this->parsingCss->save();
2330
-                $this->parsingCss->analyse('PAGE', $param);
2331
-                $this->parsingCss->setPosition();
2332
-                $this->parsingCss->fontSet();
2333
-
2334
-                // new page
2335
-                $this->_setNewPage($format, $orientation, $background, null, $resetPageNumber);
2336
-
2337
-                // automatic footer
2338
-                if (isset($param['footer'])) {
2339
-                    $lst = explode(';', $param['footer']);
2340
-                    foreach ($lst as $key => $val) $lst[$key] = trim(strtolower($val));
2341
-                    $page    = in_array('page', $lst);
2342
-                    $date    = in_array('date', $lst);
2343
-                    $hour    = in_array('heure', $lst);
2344
-                    $form    = in_array('form', $lst);
2345
-                } else {
2346
-                    $page    = null;
2347
-                    $date    = null;
2348
-                    $hour    = null;
2349
-                    $form    = null;
2350
-                }
2351
-                $this->pdf->SetMyFooter($page, $date, $hour, $form);
2352
-            // else => we use the last page set used
2353
-            } else {
2354
-                $this->parsingCss->save();
2355
-                $this->parsingCss->analyse('PAGE', $param);
2356
-                $this->parsingCss->setPosition();
2357
-                $this->parsingCss->fontSet();
2358
-
2359
-                $this->_setNewPage(null, null, null, null, $resetPageNumber);
2360
-            }
2361
-
2362
-            return true;
2363
-        }
2364
-
2365
-        /**
2366
-         * tag : PAGE
2367
-         * mode : CLOSE
2368
-         *
2369
-         * @param  array $param
2370
-         * @return boolean
2371
-         */
2372
-        protected function _tag_close_PAGE($param)
2373
-        {
2374
-            if ($this->_isForOneLine) return false;
2375
-
2376
-            $this->_maxH = 0;
2377
-
2378
-            $this->parsingCss->load();
2379
-            $this->parsingCss->fontSet();
2380
-
2381
-            if ($this->_debugActif) $this->_DEBUG_add('PAGE '.$this->_page, false);
2382
-
2383
-            return true;
2384
-        }
2385
-
2386
-        /**
2387
-         * tag : PAGE_HEADER
2388
-         * mode : OPEN
2389
-         *
2390
-         * @param  array $param
2391
-         * @return boolean
2392
-         */
2393
-        protected function _tag_open_PAGE_HEADER($param)
2394
-        {
2395
-            if ($this->_isForOneLine) return false;
2396
-
2397
-            $this->_subHEADER = array();
2398
-            for ($this->_parsePos; $this->_parsePos<count($this->parsingHtml->code); $this->_parsePos++) {
2399
-                $action = $this->parsingHtml->code[$this->_parsePos];
2400
-                if ($action['name']=='page_header') $action['name']='page_header_sub';
2401
-                $this->_subHEADER[] = $action;
2402
-                if (strtolower($action['name'])=='page_header_sub' && $action['close']) break;
2403
-            }
2404
-
2405
-            $this->_setPageHeader();
2406
-
2407
-            return true;
2408
-        }
2409
-
2410
-        /**
2411
-         * tag : PAGE_FOOTER
2412
-         * mode : OPEN
2413
-         *
2414
-         * @param  array $param
2415
-         * @return boolean
2416
-         */
2417
-        protected function _tag_open_PAGE_FOOTER($param)
2418
-        {
2419
-            if ($this->_isForOneLine) return false;
2420
-
2421
-            $this->_subFOOTER = array();
2422
-            for ($this->_parsePos; $this->_parsePos<count($this->parsingHtml->code); $this->_parsePos++) {
2423
-                $action = $this->parsingHtml->code[$this->_parsePos];
2424
-                if ($action['name']=='page_footer') $action['name']='page_footer_sub';
2425
-                $this->_subFOOTER[] = $action;
2426
-                if (strtolower($action['name'])=='page_footer_sub' && $action['close']) break;
2427
-            }
2428
-
2429
-            $this->_setPageFooter();
2430
-
2431
-            return true;
2432
-        }
2433
-
2434
-        /**
2435
-         * It is not a real tag. Does not use it directly
2436
-         *
2437
-         * @param  array $param
2438
-         * @return boolean
2439
-         */
2440
-        protected function _tag_open_PAGE_HEADER_SUB($param)
2441
-        {
2442
-            if ($this->_isForOneLine) return false;
2443
-
2444
-            // save the current stat
2445
-            $this->_subSTATES = array();
2446
-            $this->_subSTATES['x']  = $this->pdf->getX();
2447
-            $this->_subSTATES['y']  = $this->pdf->getY();
2448
-            $this->_subSTATES['s']  = $this->parsingCss->value;
2449
-            $this->_subSTATES['t']  = $this->parsingCss->table;
2450
-            $this->_subSTATES['ml'] = $this->_margeLeft;
2451
-            $this->_subSTATES['mr'] = $this->_margeRight;
2452
-            $this->_subSTATES['mt'] = $this->_margeTop;
2453
-            $this->_subSTATES['mb'] = $this->_margeBottom;
2454
-            $this->_subSTATES['mp'] = $this->_pageMarges;
2455
-
2456
-            // new stat for the header
2457
-            $this->_pageMarges = array();
2458
-            $this->_margeLeft    = $this->_defaultLeft;
2459
-            $this->_margeRight   = $this->_defaultRight;
2460
-            $this->_margeTop     = $this->_defaultTop;
2461
-            $this->_margeBottom  = $this->_defaultBottom;
2462
-            $this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
2463
-            $this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
2464
-            $this->pdf->setXY($this->_defaultLeft, $this->_defaultTop);
2465
-
2466
-            $this->parsingCss->initStyle();
2467
-            $this->parsingCss->resetStyle();
2468
-            $this->parsingCss->value['width'] = $this->pdf->getW() - $this->_defaultLeft - $this->_defaultRight;
2469
-            $this->parsingCss->table = array();
2470
-
2471
-            $this->parsingCss->save();
2472
-            $this->parsingCss->analyse('page_header_sub', $param);
2473
-            $this->parsingCss->setPosition();
2474
-            $this->parsingCss->fontSet();
2475
-            $this->_setNewPositionForNewLine();
2476
-            return true;
2477
-        }
2478
-
2479
-        /**
2480
-         * It is not a real tag. Does not use it directly
2481
-         *
2482
-         * @param  array $param
2483
-         * @return boolean
2484
-         */
2485
-        protected function _tag_close_PAGE_HEADER_SUB($param)
2486
-        {
2487
-            if ($this->_isForOneLine) return false;
2488
-
2489
-            $this->parsingCss->load();
2490
-
2491
-            // restore the stat
2492
-            $this->parsingCss->value = $this->_subSTATES['s'];
2493
-            $this->parsingCss->table = $this->_subSTATES['t'];
2494
-            $this->_pageMarges       = $this->_subSTATES['mp'];
2495
-            $this->_margeLeft        = $this->_subSTATES['ml'];
2496
-            $this->_margeRight       = $this->_subSTATES['mr'];
2497
-            $this->_margeTop         = $this->_subSTATES['mt'];
2498
-            $this->_margeBottom      = $this->_subSTATES['mb'];
2499
-            $this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
2500
-            $this->pdf->setbMargin($this->_margeBottom);
2501
-            $this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
2502
-            $this->pdf->setXY($this->_subSTATES['x'], $this->_subSTATES['y']);
2503
-
2504
-            $this->parsingCss->fontSet();
2505
-            $this->_maxH = 0;
2506
-
2507
-            return true;
2508
-        }
2509
-
2510
-        /**
2511
-         * It is not a real tag. Does not use it directly
2512
-         *
2513
-         * @param  array $param
2514
-         * @return boolean
2515
-         */
2516
-        protected function _tag_open_PAGE_FOOTER_SUB($param)
2517
-        {
2518
-            if ($this->_isForOneLine) return false;
2519
-
2520
-            // save the current stat
2521
-            $this->_subSTATES = array();
2522
-            $this->_subSTATES['x']    = $this->pdf->getX();
2523
-            $this->_subSTATES['y']    = $this->pdf->getY();
2524
-            $this->_subSTATES['s']    = $this->parsingCss->value;
2525
-            $this->_subSTATES['t']    = $this->parsingCss->table;
2526
-            $this->_subSTATES['ml']    = $this->_margeLeft;
2527
-            $this->_subSTATES['mr']    = $this->_margeRight;
2528
-            $this->_subSTATES['mt']    = $this->_margeTop;
2529
-            $this->_subSTATES['mb']    = $this->_margeBottom;
2530
-            $this->_subSTATES['mp']    = $this->_pageMarges;
2531
-
2532
-            // new stat for the footer
2533
-            $this->_pageMarges  = array();
2534
-            $this->_margeLeft   = $this->_defaultLeft;
2535
-            $this->_margeRight  = $this->_defaultRight;
2536
-            $this->_margeTop    = $this->_defaultTop;
2537
-            $this->_margeBottom = $this->_defaultBottom;
2538
-            $this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
2539
-            $this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
2540
-            $this->pdf->setXY($this->_defaultLeft, $this->_defaultTop);
2541
-
2542
-            $this->parsingCss->initStyle();
2543
-            $this->parsingCss->resetStyle();
2544
-            $this->parsingCss->value['width']    = $this->pdf->getW() - $this->_defaultLeft - $this->_defaultRight;
2545
-            $this->parsingCss->table                = array();
2546
-
2547
-            // we create a sub HTML2PFDF, and we execute on it the content of the footer, to get the height of it
2548
-            $sub = null;
2549
-            $this->_createSubHTML($sub);
2550
-            $sub->parsingHtml->code = $this->parsingHtml->getLevel($this->_parsePos);
2551
-            $sub->_makeHTMLcode();
2552
-            $this->pdf->setY($this->pdf->getH() - $sub->_maxY - $this->_defaultBottom - 0.01);
2553
-            $this->_destroySubHTML($sub);
2554
-
2555
-            $this->parsingCss->save();
2556
-            $this->parsingCss->analyse('page_footer_sub', $param);
2557
-            $this->parsingCss->setPosition();
2558
-            $this->parsingCss->fontSet();
2559
-            $this->_setNewPositionForNewLine();
2560
-
2561
-            return true;
2562
-        }
2563
-
2564
-        /**
2565
-         * It is not a real tag. Does not use it directly
2566
-         *
2567
-         * @param  array $param
2568
-         * @return boolean
2569
-         */
2570
-        protected function _tag_close_PAGE_FOOTER_SUB($param)
2571
-        {
2572
-            if ($this->_isForOneLine) return false;
2573
-
2574
-            $this->parsingCss->load();
2575
-
2576
-            $this->parsingCss->value                = $this->_subSTATES['s'];
2577
-            $this->parsingCss->table                = $this->_subSTATES['t'];
2578
-            $this->_pageMarges                 = $this->_subSTATES['mp'];
2579
-            $this->_margeLeft                = $this->_subSTATES['ml'];
2580
-            $this->_margeRight                = $this->_subSTATES['mr'];
2581
-            $this->_margeTop                    = $this->_subSTATES['mt'];
2582
-            $this->_margeBottom                = $this->_subSTATES['mb'];
2583
-            $this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
2584
-            $this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
2585
-            $this->pdf->setXY($this->_subSTATES['x'], $this->_subSTATES['y']);
2586
-
2587
-            $this->parsingCss->fontSet();
2588
-            $this->_maxH = 0;
2589
-
2590
-            return true;
2591
-        }
2592
-
2593
-        /**
2594
-         * tag : NOBREAK
2595
-         * mode : OPEN
2596
-         *
2597
-         * @param  array $param
2598
-         * @return boolean
2599
-         */
2600
-        protected function _tag_open_NOBREAK($param)
2601
-        {
2602
-            if ($this->_isForOneLine) return false;
2603
-
2604
-            $this->_maxH = 0;
2605
-
2606
-            // create a sub HTML2PDF to execute the content of the tag, to get the dimensions
2607
-            $sub = null;
2608
-            $this->_createSubHTML($sub);
2609
-            $sub->parsingHtml->code = $this->parsingHtml->getLevel($this->_parsePos);
2610
-            $sub->_makeHTMLcode();
2611
-            $y = $this->pdf->getY();
2612
-
2613
-            // if the content does not fit on the page => new page
2614
-            if (
2615
-                $sub->_maxY < ($this->pdf->getH() - $this->pdf->gettMargin()-$this->pdf->getbMargin()) &&
2616
-                $y + $sub->_maxY>=($this->pdf->getH() - $this->pdf->getbMargin())
2617
-            ) {
2618
-                $this->_setNewPage();
2619
-            }
2620
-
2621
-            // destroy the sub HTML2PDF
2622
-            $this->_destroySubHTML($sub);
2623
-
2624
-            return true;
2625
-        }
2626
-
2627
-
2628
-        /**
2629
-         * tag : NOBREAK
2630
-         * mode : CLOSE
2631
-         *
2632
-         * @param  array $param
2633
-         * @return boolean
2634
-         */
2635
-        protected function _tag_close_NOBREAK($param)
2636
-        {
2637
-            if ($this->_isForOneLine) return false;
2638
-
2639
-            $this->_maxH = 0;
2640
-
2641
-            return true;
2642
-        }
2643
-
2644
-        /**
2645
-         * tag : DIV
2646
-         * mode : OPEN
2647
-         *
2648
-         * @param  array $param
2649
-         * @param  string $other name of tag that used the div tag
2650
-         * @return boolean
2651
-         */
2652
-        protected function _tag_open_DIV($param, $other = 'div')
2653
-        {
2654
-            if ($this->_isForOneLine) return false;
2655
-            if ($this->_debugActif) $this->_DEBUG_add(strtoupper($other), true);
2656
-
2657
-            $this->parsingCss->save();
2658
-            $this->parsingCss->analyse($other, $param);
2659
-            $this->parsingCss->fontSet();
2660
-
2661
-            // for fieldset and legend
2662
-            if (in_array($other, array('fieldset', 'legend'))) {
2663
-                if (isset($param['moveTop']))  $this->parsingCss->value['margin']['t']    += $param['moveTop'];
2664
-                if (isset($param['moveLeft'])) $this->parsingCss->value['margin']['l']    += $param['moveLeft'];
2665
-                if (isset($param['moveDown'])) $this->parsingCss->value['margin']['b']    += $param['moveDown'];
2666
-            }
2667
-
2668
-            $alignObject = null;
2669
-            if ($this->parsingCss->value['margin-auto']) $alignObject = 'center';
2670
-
2671
-            $marge = array();
2672
-            $marge['l'] = $this->parsingCss->value['border']['l']['width'] + $this->parsingCss->value['padding']['l']+0.03;
2673
-            $marge['r'] = $this->parsingCss->value['border']['r']['width'] + $this->parsingCss->value['padding']['r']+0.03;
2674
-            $marge['t'] = $this->parsingCss->value['border']['t']['width'] + $this->parsingCss->value['padding']['t']+0.03;
2675
-            $marge['b'] = $this->parsingCss->value['border']['b']['width'] + $this->parsingCss->value['padding']['b']+0.03;
2676
-
2677
-            // extract the content of the div
2678
-            $level = $this->parsingHtml->getLevel($this->_parsePos);
2679
-
2680
-            // create a sub HTML2PDF to get the dimensions of the content of the div
2681
-            $w = 0; $h = 0;
2682
-            if (count($level)) {
2683
-                $sub = null;
2684
-                $this->_createSubHTML($sub);
2685
-                $sub->parsingHtml->code = $level;
2686
-                $sub->_makeHTMLcode();
2687
-                $w = $sub->_maxX;
2688
-                $h = $sub->_maxY;
2689
-                $this->_destroySubHTML($sub);
2690
-            }
2691
-            $wReel = $w;
2692
-            $hReel = $h;
2693
-
2694
-            $w+= $marge['l']+$marge['r']+0.001;
2695
-            $h+= $marge['t']+$marge['b']+0.001;
2696
-
2697
-            if ($this->parsingCss->value['overflow']=='hidden') {
2698
-                $overW = max($w, $this->parsingCss->value['width']);
2699
-                $overH = max($h, $this->parsingCss->value['height']);
2700
-                $overflow = true;
2701
-                $this->parsingCss->value['old_maxX'] = $this->_maxX;
2702
-                $this->parsingCss->value['old_maxY'] = $this->_maxY;
2703
-                $this->parsingCss->value['old_maxH'] = $this->_maxH;
2704
-                $this->parsingCss->value['old_overflow'] = $this->_isInOverflow;
2705
-                $this->_isInOverflow = true;
2706
-            } else {
2707
-                $overW = null;
2708
-                $overH = null;
2709
-                $overflow = false;
2710
-                $this->parsingCss->value['width']    = max($w, $this->parsingCss->value['width']);
2711
-                $this->parsingCss->value['height']    = max($h, $this->parsingCss->value['height']);
2712
-            }
2713
-
2714
-            switch($this->parsingCss->value['rotate'])
2715
-            {
2716
-                case 90:
2717
-                    $tmp = $overH; $overH = $overW; $overW = $tmp;
2718
-                    $tmp = $hReel; $hReel = $wReel; $wReel = $tmp;
2719
-                    unset($tmp);
2720
-                    $w = $this->parsingCss->value['height'];
2721
-                    $h = $this->parsingCss->value['width'];
2722
-                    $tX =-$h;
2723
-                    $tY = 0;
2724
-                    break;
2725
-
2726
-                case 180:
2727
-                    $w = $this->parsingCss->value['width'];
2728
-                    $h = $this->parsingCss->value['height'];
2729
-                    $tX = -$w;
2730
-                    $tY = -$h;
2731
-                    break;
2732
-
2733
-                case 270:
2734
-                    $tmp = $overH; $overH = $overW; $overW = $tmp;
2735
-                    $tmp = $hReel; $hReel = $wReel; $wReel = $tmp;
2736
-                    unset($tmp);
2737
-                    $w = $this->parsingCss->value['height'];
2738
-                    $h = $this->parsingCss->value['width'];
2739
-                    $tX = 0;
2740
-                    $tY =-$w;
2741
-                    break;
2742
-
2743
-                default:
2744
-                    $w = $this->parsingCss->value['width'];
2745
-                    $h = $this->parsingCss->value['height'];
2746
-                    $tX = 0;
2747
-                    $tY = 0;
2748
-                    break;
2749
-            }
2750
-
2751
-            if (!$this->parsingCss->value['position']) {
2752
-                if (
2753
-                    $w < ($this->pdf->getW() - $this->pdf->getlMargin()-$this->pdf->getrMargin()) &&
2754
-                    $this->pdf->getX() + $w>=($this->pdf->getW() - $this->pdf->getrMargin())
2755
-                    )
2756
-                    $this->_tag_open_BR(array());
2757
-
2758
-                if (
2759
-                        ($h < ($this->pdf->getH() - $this->pdf->gettMargin()-$this->pdf->getbMargin())) &&
2760
-                        ($this->pdf->getY() + $h>=($this->pdf->getH() - $this->pdf->getbMargin())) &&
2761
-                        !$this->_isInOverflow
2762
-                    )
2763
-                    $this->_setNewPage();
2764
-
2765
-                $old = $this->parsingCss->getOldValues();
2766
-                $parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
2767
-
2768
-                if ($parentWidth>$w) {
2769
-                    if ($alignObject=='center')        $this->pdf->setX($this->pdf->getX() + ($parentWidth-$w)*0.5);
2770
-                    else if ($alignObject=='right')    $this->pdf->setX($this->pdf->getX() + $parentWidth-$w);
2771
-                }
2772
-
2773
-                $this->parsingCss->setPosition();
2774
-            } else {
2775
-                $old = $this->parsingCss->getOldValues();
2776
-                $parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
2777
-
2778
-                if ($parentWidth>$w) {
2779
-                    if ($alignObject=='center')        $this->pdf->setX($this->pdf->getX() + ($parentWidth-$w)*0.5);
2780
-                    else if ($alignObject=='right')    $this->pdf->setX($this->pdf->getX() + $parentWidth-$w);
2781
-                }
2782
-
2783
-                $this->parsingCss->setPosition();
2784
-                $this->_saveMax();
2785
-                $this->_maxX = 0;
2786
-                $this->_maxY = 0;
2787
-                $this->_maxH = 0;
2788
-                $this->_maxE = 0;
2789
-            }
2790
-
2791
-            if ($this->parsingCss->value['rotate']) {
2792
-                $this->pdf->startTransform();
2793
-                $this->pdf->setRotation($this->parsingCss->value['rotate']);
2794
-                $this->pdf->setTranslate($tX, $tY);
2795
-            }
2796
-
2797
-            $this->_drawRectangle(
2798
-                $this->parsingCss->value['x'],
2799
-                $this->parsingCss->value['y'],
2800
-                $this->parsingCss->value['width'],
2801
-                $this->parsingCss->value['height'],
2802
-                $this->parsingCss->value['border'],
2803
-                $this->parsingCss->value['padding'],
2804
-                0,
2805
-                $this->parsingCss->value['background']
2806
-            );
2807
-
2808
-            $marge = array();
2809
-            $marge['l'] = $this->parsingCss->value['border']['l']['width'] + $this->parsingCss->value['padding']['l']+0.03;
2810
-            $marge['r'] = $this->parsingCss->value['border']['r']['width'] + $this->parsingCss->value['padding']['r']+0.03;
2811
-            $marge['t'] = $this->parsingCss->value['border']['t']['width'] + $this->parsingCss->value['padding']['t']+0.03;
2812
-            $marge['b'] = $this->parsingCss->value['border']['b']['width'] + $this->parsingCss->value['padding']['b']+0.03;
2813
-
2814
-            $this->parsingCss->value['width'] -= $marge['l']+$marge['r'];
2815
-            $this->parsingCss->value['height']-= $marge['t']+$marge['b'];
2816
-
2817
-            $xCorr = 0;
2818
-            $yCorr = 0;
2819
-            if (!$this->_subPart && !$this->_isSubPart) {
2820
-                switch($this->parsingCss->value['text-align'])
2821
-                {
2822
-                    case 'right':
2823
-                        $xCorr = ($this->parsingCss->value['width']-$wReel);
2824
-                        break;
2825
-                    case 'center':
2826
-                        $xCorr = ($this->parsingCss->value['width']-$wReel)*0.5;
2827
-                        break;
2828
-                }
2829
-                if ($xCorr>0) $xCorr=0;
2830
-                switch($this->parsingCss->value['vertical-align'])
2831
-                {
2832
-                    case 'bottom':
2833
-                        $yCorr = ($this->parsingCss->value['height']-$hReel);
2834
-                        break;
2835
-                    case 'middle':
2836
-                        $yCorr = ($this->parsingCss->value['height']-$hReel)*0.5;
2837
-                        break;
2838
-                }
2839
-            }
2840
-
2841
-            if ($overflow) {
2842
-                $overW-= $marge['l']+$marge['r'];
2843
-                $overH-= $marge['t']+$marge['b'];
2844
-                $this->pdf->clippingPathStart(
2845
-                    $this->parsingCss->value['x']+$marge['l'],
2846
-                    $this->parsingCss->value['y']+$marge['t'],
2847
-                    $this->parsingCss->value['width'],
2848
-                    $this->parsingCss->value['height']
2849
-                );
2850
-
2851
-                $this->parsingCss->value['x']+= $xCorr;
2852
-
2853
-                // marges from the dimension of the content
2854
-                $mL = $this->parsingCss->value['x']+$marge['l'];
2855
-                $mR = $this->pdf->getW() - $mL - $overW;
2856
-            } else {
2857
-                // marges from the dimension of the div
2858
-                $mL = $this->parsingCss->value['x']+$marge['l'];
2859
-                $mR = $this->pdf->getW() - $mL - $this->parsingCss->value['width'];
2860
-            }
2861
-
2862
-            $x = $this->parsingCss->value['x']+$marge['l'];
2863
-            $y = $this->parsingCss->value['y']+$marge['t']+$yCorr;
2864
-            $this->_saveMargin($mL, 0, $mR);
2865
-            $this->pdf->setXY($x, $y);
2866
-
2867
-            $this->_setNewPositionForNewLine();
2868
-
2869
-            return true;
2870
-        }
2871
-
2872
-        /**
2873
-         * tag : BLOCKQUOTE
2874
-         * mode : OPEN
2875
-         *
2876
-         * @param  array $param
2877
-         * @return boolean
2878
-         */
2879
-        protected function _tag_open_BLOCKQUOTE($param)
2880
-        {
2881
-            return $this->_tag_open_DIV($param, 'blockquote');
2882
-        }
2883
-
2884
-        /**
2885
-         * tag : LEGEND
2886
-         * mode : OPEN
2887
-         *
2888
-         * @param  array $param
2889
-         * @return boolean
2890
-         */
2891
-        protected function _tag_open_LEGEND($param)
2892
-        {
2893
-            return $this->_tag_open_DIV($param, 'legend');
2894
-        }
2895
-
2896
-        /**
2897
-         * tag : FIELDSET
2898
-         * mode : OPEN
2899
-         *
2900
-         * @author Pavel Kochman
2901
-         * @param  array $param
2902
-         * @return boolean
2903
-         */
2904
-        protected function _tag_open_FIELDSET($param)
2905
-        {
2906
-
2907
-            $this->parsingCss->save();
2908
-            $this->parsingCss->analyse('fieldset', $param);
2909
-
2910
-            // get height of LEGEND element and make fieldset corrections
2911
-            for ($tempPos = $this->_parsePos + 1; $tempPos<count($this->parsingHtml->code); $tempPos++) {
2912
-                $action = $this->parsingHtml->code[$tempPos];
2913
-                if ($action['name'] == 'fieldset') break;
2914
-                if ($action['name'] == 'legend' && !$action['close']) {
2915
-                    $legendOpenPos = $tempPos;
2916
-
2917
-                    $sub = null;
2918
-                    $this->_createSubHTML($sub);
2919
-                    $sub->parsingHtml->code = $this->parsingHtml->getLevel($tempPos - 1);
2920
-
2921
-                    $res = null;
2922
-                    for ($sub->_parsePos = 0; $sub->_parsePos<count($sub->parsingHtml->code); $sub->_parsePos++) {
2923
-                        $action = $sub->parsingHtml->code[$sub->_parsePos];
2924
-                        $sub->_executeAction($action);
2925
-
2926
-                        if ($action['name'] == 'legend' && $action['close'])
2927
-                            break;
2928
-                    }
2929
-
2930
-                    $legendH = $sub->_maxY;
2931
-                    $this->_destroySubHTML($sub);
2932
-
2933
-                    $move = $this->parsingCss->value['padding']['t'] + $this->parsingCss->value['border']['t']['width'] + 0.03;
2934
-
2935
-                    $param['moveTop'] = $legendH / 2;
2936
-
2937
-                    $this->parsingHtml->code[$legendOpenPos]['param']['moveTop'] = - ($legendH / 2 + $move);
2938
-                    $this->parsingHtml->code[$legendOpenPos]['param']['moveLeft'] = 2 - $this->parsingCss->value['border']['l']['width'] - $this->parsingCss->value['padding']['l'];
2939
-                    $this->parsingHtml->code[$legendOpenPos]['param']['moveDown'] = $move;
2940
-                    break;
2941
-                }
2942
-            }
2943
-            $this->parsingCss->load();
2944
-
2945
-            return $this->_tag_open_DIV($param, 'fieldset');
2946
-        }
2947
-
2948
-        /**
2949
-         * tag : DIV
2950
-         * mode : CLOSE
2951
-         *
2952
-         * @param  array $param
2953
-         * @param  string $other name of tag that used the div tag
2954
-         * @return boolean
2955
-         */
2956
-        protected function _tag_close_DIV($param, $other='div')
2957
-        {
2958
-            if ($this->_isForOneLine) return false;
2959
-
2960
-            if ($this->parsingCss->value['overflow']=='hidden') {
2961
-                $this->_maxX = $this->parsingCss->value['old_maxX'];
2962
-                $this->_maxY = $this->parsingCss->value['old_maxY'];
2963
-                $this->_maxH = $this->parsingCss->value['old_maxH'];
2964
-                $this->_isInOverflow = $this->parsingCss->value['old_overflow'];
2965
-                $this->pdf->clippingPathStop();
2966
-            }
2967
-
2968
-            if ($this->parsingCss->value['rotate'])
2969
-                $this->pdf->stopTransform();
2970
-
2971
-            $marge = array();
2972
-            $marge['l'] = $this->parsingCss->value['border']['l']['width'] + $this->parsingCss->value['padding']['l']+0.03;
2973
-            $marge['r'] = $this->parsingCss->value['border']['r']['width'] + $this->parsingCss->value['padding']['r']+0.03;
2974
-            $marge['t'] = $this->parsingCss->value['border']['t']['width'] + $this->parsingCss->value['padding']['t']+0.03;
2975
-            $marge['b'] = $this->parsingCss->value['border']['b']['width'] + $this->parsingCss->value['padding']['b']+0.03;
2976
-
2977
-            $x = $this->parsingCss->value['x'];
2978
-            $y = $this->parsingCss->value['y'];
2979
-            $w = $this->parsingCss->value['width']+$marge['l']+$marge['r']+$this->parsingCss->value['margin']['r'];
2980
-            $h = $this->parsingCss->value['height']+$marge['t']+$marge['b']+$this->parsingCss->value['margin']['b'];
2981
-
2982
-            switch($this->parsingCss->value['rotate'])
2983
-            {
2984
-                case 90:
2985
-                    $t = $w; $w = $h; $h = $t;
2986
-                    break;
2987
-
2988
-                case 270:
2989
-                    $t = $w; $w = $h; $h = $t;
2990
-                    break;
2991
-
2992
-                default:
2993
-                    break;
2994
-            }
2995
-
2996
-
2997
-            if ($this->parsingCss->value['position']!='absolute') {
2998
-                $this->pdf->setXY($x+$w, $y);
2999
-
3000
-                $this->_maxX = max($this->_maxX, $x+$w);
3001
-                $this->_maxY = max($this->_maxY, $y+$h);
3002
-                $this->_maxH = max($this->_maxH, $h);
3003
-            } else {
3004
-                $this->pdf->setXY($this->parsingCss->value['xc'], $this->parsingCss->value['yc']);
3005
-
3006
-                $this->_loadMax();
3007
-            }
3008
-
3009
-            $block = ($this->parsingCss->value['display']!='inline' && $this->parsingCss->value['position']!='absolute');
3010
-
3011
-            $this->parsingCss->load();
3012
-            $this->parsingCss->fontSet();
3013
-            $this->_loadMargin();
3014
-
3015
-            if ($block) $this->_tag_open_BR(array());
3016
-            if ($this->_debugActif) $this->_DEBUG_add(strtoupper($other), false);
3017
-
3018
-            return true;
3019
-        }
3020
-
3021
-        /**
3022
-         * tag : BLOCKQUOTE
3023
-         * mode : CLOSE
3024
-         *
3025
-         * @param  array $param
3026
-         * @return boolean
3027
-         */
3028
-        protected function _tag_close_BLOCKQUOTE($param)
3029
-        {
3030
-            return $this->_tag_close_DIV($param, 'blockquote');
3031
-        }
3032
-
3033
-        /**
3034
-         * tag : FIELDSET
3035
-         * mode : CLOSE
3036
-         *
3037
-         * @param  array $param
3038
-         * @return boolean
3039
-         */
3040
-        protected function _tag_close_FIELDSET($param)
3041
-        {
3042
-            return $this->_tag_close_DIV($param, 'fieldset');
3043
-        }
3044
-
3045
-        /**
3046
-         * tag : LEGEND
3047
-         * mode : CLOSE
3048
-         *
3049
-         * @param  array $param
3050
-         * @return boolean
3051
-         */
3052
-        protected function _tag_close_LEGEND($param)
3053
-        {
3054
-            return $this->_tag_close_DIV($param, 'legend');
3055
-        }
3056
-
3057
-        /**
3058
-         * tag : BARCODE
3059
-         * mode : OPEN
3060
-         *
3061
-         * @param  array $param
3062
-         * @return boolean
3063
-         */
3064
-        protected function _tag_open_BARCODE($param)
3065
-        {
3066
-            // for  compatibility with old versions < 3.29
3067
-            $lstBarcode = array();
3068
-            $lstBarcode['UPC_A']  =    'UPCA';
3069
-            $lstBarcode['CODE39'] =    'C39';
3070
-
3071
-            if (!isset($param['type']))     $param['type'] = 'C39';
3072
-            if (!isset($param['value']))    $param['value']    = 0;
3073
-            if (!isset($param['label']))    $param['label']    = 'label';
3074
-            if (!isset($param['style']['color'])) $param['style']['color'] = '#000000';
3075
-
3076
-            if ($this->_testIsDeprecated && (isset($param['bar_h']) || isset($param['bar_w'])))
3077
-                throw new HTML2PDF_exception(9, array('BARCODE', 'bar_h, bar_w'));
3078
-
3079
-            $param['type'] = strtoupper($param['type']);
3080
-            if (isset($lstBarcode[$param['type']])) $param['type'] = $lstBarcode[$param['type']];
3081
-
3082
-            $this->parsingCss->save();
3083
-            $this->parsingCss->analyse('barcode', $param);
3084
-            $this->parsingCss->setPosition();
3085
-            $this->parsingCss->fontSet();
3086
-
3087
-            $x = $this->pdf->getX();
3088
-            $y = $this->pdf->getY();
3089
-            $w = $this->parsingCss->value['width'];    if (!$w) $w = $this->parsingCss->ConvertToMM('50mm');
3090
-            $h = $this->parsingCss->value['height'];    if (!$h) $h = $this->parsingCss->ConvertToMM('10mm');
3091
-            $txt = ($param['label']!=='none' ? $this->parsingCss->value['font-size'] : false);
3092
-            $c = $this->parsingCss->value['color'];
3093
-            $infos = $this->pdf->myBarcode($param['value'], $param['type'], $x, $y, $w, $h, $txt, $c);
3094
-
3095
-            $this->_maxX = max($this->_maxX, $x+$infos[0]);
3096
-            $this->_maxY = max($this->_maxY, $y+$infos[1]);
3097
-            $this->_maxH = max($this->_maxH, $infos[1]);
3098
-            $this->_maxE++;
3099
-
3100
-            $this->pdf->setXY($x+$infos[0], $y);
3101
-
3102
-            $this->parsingCss->load();
3103
-            $this->parsingCss->fontSet();
3104
-
3105
-            return true;
3106
-        }
3107
-
3108
-        /**
3109
-         * tag : BARCODE
3110
-         * mode : CLOSE
3111
-         *
3112
-         * @param  array $param
3113
-         * @return boolean
3114
-         */
3115
-        protected function _tag_close_BARCODE($param)
3116
-        {
3117
-            // there is nothing to do here
3118
-
3119
-            return true;
3120
-        }
3121
-
3122
-        /**
3123
-         * tag : QRCODE
3124
-         * mode : OPEN
3125
-         *
3126
-         * @param  array $param
3127
-         * @return boolean
3128
-         */
3129
-        protected function _tag_open_QRCODE($param)
3130
-        {
3131
-            if ($this->_testIsDeprecated && (isset($param['size']) || isset($param['noborder'])))
3132
-                throw new HTML2PDF_exception(9, array('QRCODE', 'size, noborder'));
3133
-
3134
-            if ($this->_debugActif) $this->_DEBUG_add('QRCODE');
3135
-
3136
-            if (!isset($param['value']))                     $param['value'] = '';
3137
-            if (!isset($param['ec']))                        $param['ec'] = 'H';
3138
-            if (!isset($param['style']['color']))            $param['style']['color'] = '#000000';
3139
-            if (!isset($param['style']['background-color'])) $param['style']['background-color'] = '#FFFFFF';
3140
-            if (isset($param['style']['border'])) {
3141
-                $borders = $param['style']['border']!='none';
3142
-                unset($param['style']['border']);
3143
-            } else {
3144
-                $borders = true;
3145
-            }
3146
-
3147
-            if ($param['value']==='') return true;
3148
-            if (!in_array($param['ec'], array('L', 'M', 'Q', 'H'))) $param['ec'] = 'H';
3149
-
3150
-            $this->parsingCss->save();
3151
-            $this->parsingCss->analyse('qrcode', $param);
3152
-            $this->parsingCss->setPosition();
3153
-            $this->parsingCss->fontSet();
3154
-
3155
-            $x = $this->pdf->getX();
3156
-            $y = $this->pdf->getY();
3157
-            $w = $this->parsingCss->value['width'];
3158
-            $h = $this->parsingCss->value['height'];
3159
-            $size = max($w, $h); if (!$size) $size = $this->parsingCss->ConvertToMM('50mm');
3160
-
3161
-            $style = array(
3162
-                    'fgcolor' => $this->parsingCss->value['color'],
3163
-                    'bgcolor' => $this->parsingCss->value['background']['color'],
3164
-                );
3165
-
3166
-            if ($borders) {
3167
-                $style['border'] = true;
3168
-                $style['padding'] = 'auto';
3169
-            } else {
3170
-                $style['border'] = false;
3171
-                $style['padding'] = 0;
3172
-            }
3173
-
3174
-            if (!$this->_subPart && !$this->_isSubPart) {
3175
-                $this->pdf->write2DBarcode($param['value'], 'QRCODE,'.$param['ec'], $x, $y, $size, $size, $style);
3176
-            }
3177
-
3178
-            $this->_maxX = max($this->_maxX, $x+$size);
3179
-            $this->_maxY = max($this->_maxY, $y+$size);
3180
-            $this->_maxH = max($this->_maxH, $size);
3181
-            $this->_maxE++;
3182
-
3183
-            $this->pdf->setX($x+$size);
3184
-
3185
-            $this->parsingCss->load();
3186
-            $this->parsingCss->fontSet();
3187
-
3188
-            return true;
3189
-        }
3190
-
3191
-        /**
3192
-         * tag : QRCODE
3193
-         * mode : CLOSE
3194
-         *
3195
-         * @param  array $param
3196
-         * @return boolean
3197
-         */
3198
-        protected function _tag_close_QRCODE($param)
3199
-        {
3200
-            // there is nothing to do here
3201
-
3202
-            return true;
3203
-        }
3204
-
3205
-        /**
3206
-         * tag : BOOKMARK
3207
-         * mode : OPEN
3208
-         *
3209
-         * @param  array $param
3210
-         * @return boolean
3211
-         */
3212
-        protected function _tag_open_BOOKMARK($param)
3213
-        {
3214
-            $titre = isset($param['title']) ? trim($param['title']) : '';
3215
-            $level = isset($param['level']) ? floor($param['level']) : 0;
3216
-
3217
-            if ($level<0) $level = 0;
3218
-            if ($titre) $this->pdf->Bookmark($titre, $level, -1);
3219
-
3220
-            return true;
3221
-        }
3222
-
3223
-        /**
3224
-         * tag : BOOKMARK
3225
-         * mode : CLOSE
3226
-         *
3227
-         * @param  array $param
3228
-         * @return boolean
3229
-         */
3230
-        protected function _tag_close_BOOKMARK($param)
3231
-        {
3232
-            // there is nothing to do here
3233
-
3234
-            return true;
3235
-        }
3236
-
3237
-        /**
3238
-         * this is not a real TAG, it is just to write texts
3239
-         *
3240
-         * @param  array $param
3241
-         * @return boolean
3242
-         */
3243
-        protected function _tag_open_WRITE($param)
3244
-        {
3245
-            $fill = ($this->parsingCss->value['background']['color']!==null && $this->parsingCss->value['background']['image']===null);
3246
-            if (in_array($this->parsingCss->value['id_tag'], array('fieldset', 'legend', 'div', 'table', 'tr', 'td', 'th'))) {
3247
-                $fill = false;
3248
-            }
3249
-
3250
-            // get the text to write
3251
-            $txt = $param['txt'];
3252
-
3253
-            if ($this->_isAfterFloat) {
3254
-                $txt = ltrim($txt);
3255
-                $this->_isAfterFloat = false;
3256
-            }
3257
-
3258
-            $txt = str_replace('[[page_nb]]', $this->pdf->getMyAliasNbPages(), $txt);
3259
-            $txt = str_replace('[[page_cu]]', $this->pdf->getMyNumPage($this->_page), $txt);
3260
-
3261
-            if ($this->parsingCss->value['text-transform']!='none') {
3262
-                if ($this->parsingCss->value['text-transform']=='capitalize')
3263
-                    $txt = ucwords($txt);
3264
-                else if ($this->parsingCss->value['text-transform']=='uppercase')
3265
-                    $txt = strtoupper($txt);
3266
-                else if ($this->parsingCss->value['text-transform']=='lowercase')
3267
-                    $txt = strtolower($txt);
3268
-            }
3269
-
3270
-            // size of the text
3271
-            $h  = 1.08*$this->parsingCss->value['font-size'];
3272
-            $dh = $h*$this->parsingCss->value['mini-decal'];
3273
-            $lh = $this->parsingCss->getLineHeight();
3274
-
3275
-            // identify the align
3276
-            $align = 'L';
3277
-            if ($this->parsingCss->value['text-align']=='li_right') {
3278
-                $w = $this->parsingCss->value['width'];
3279
-                $align = 'R';
3280
-            }
3281
-
3282
-            // calculate the width of each words, and of all the sentence
3283
-            $w = 0;
3284
-            $words = explode(' ', $txt);
3285
-            foreach ($words as $k => $word) {
3286
-                $words[$k] = array($word, $this->pdf->GetStringWidth($word));
3287
-                $w+= $words[$k][1];
3288
-            }
3289
-            $space = $this->pdf->GetStringWidth(' ');
3290
-            $w+= $space*(count($words)-1);
3291
-
3292
-            // position in the text
3293
-            $currPos = 0;
3294
-
3295
-            // the bigger width of the text, after automatic break line
3296
-            $maxX = 0;
3297
-
3298
-            // position of the text
3299
-            $x = $this->pdf->getX();
3300
-            $y = $this->pdf->getY();
3301
-            $dy = $this->_getElementY($lh);
3302
-
3303
-            // margins
3304
-            list($left, $right) = $this->_getMargins($y);
3305
-
3306
-            // number of lines after automatic break line
3307
-            $nb = 0;
3308
-
3309
-            // while we have words, and the text does not fit on the line => we cut the sentence
3310
-            while ($x+$w>$right && $x<$right+$space && count($words)) {
3311
-                // adding words 1 by 1 to fit on the line
3312
-                $i=0;
3313
-                $old = array('', 0);
3314
-                $str = $words[0];
3315
-                $add = false;
3316
-                while (($x+$str[1])<$right) {
3317
-                    $i++;
3318
-                    $add = true;
3319
-
3320
-                    array_shift($words);
3321
-                    $old = $str;
3322
-
3323
-                    if (!count($words)) break;
3324
-                    $str[0].= ' '.$words[0][0];
3325
-                    $str[1]+= $space+$words[0][1];
3326
-                }
3327
-                $str = $old;
3328
-
3329
-                // if  nothing fit on the line, and if the first word does not fit on the line => the word is too long, we put it
3330
-                if ($i==0 && (($left+$words[0][1])>=$right)) {
3331
-                    $str = $words[0];
3332
-                    array_shift($words);
3333
-                    $i++;
3334
-                    $add = true;
3335
-                }
3336
-                $currPos+= ($currPos ? 1 : 0)+strlen($str[0]);
3337
-
3338
-                // write the extract sentence that fit on the page
3339
-                $wc = ($align=='L' ? $str[1] : $this->parsingCss->value['width']);
3340
-                if ($right - $left<$wc) $wc = $right - $left;
3341
-
3342
-                if (strlen($str[0])) {
3343
-                    $this->pdf->setXY($this->pdf->getX(), $y+$dh+$dy);
3344
-                    $this->pdf->Cell($wc, $h, $str[0], 0, 0, $align, $fill, $this->_isInLink);
3345
-                    $this->pdf->setXY($this->pdf->getX(), $y);
3346
-                }
3347
-                $this->_maxH = max($this->_maxH, $lh);
3348
-
3349
-                // max width
3350
-                $maxX = max($maxX, $this->pdf->getX());
3351
-
3352
-                // new position and new width for the "while"
3353
-                $w-= $str[1];
3354
-                $y = $this->pdf->getY();
3355
-                $x = $this->pdf->getX();
3356
-                $dy = $this->_getElementY($lh);
3357
-
3358
-                // if we have again words to write
3359
-                if (count($words)) {
3360
-                    // remove the space at the end
3361
-                    if ($add) $w-= $space;
3362
-
3363
-                    // if we don't add any word, and if the first word is empty => useless space to skip
3364
-                    if (!$add && $words[0][0]==='') {
3365
-                        array_shift($words);
3366
-                    }
3367
-
3368
-                    // if it is just to calculate for one line => adding the number of words
3369
-                    if ($this->_isForOneLine) {
3370
-                        $this->_maxE+= $i;
3371
-                        $this->_maxX = max($this->_maxX, $maxX);
3372
-                        return null;
3373
-                    }
3374
-
3375
-                    // automatic line break
3376
-                    $this->_tag_open_BR(array('style' => ''), $currPos);
3377
-
3378
-                    // new position
3379
-                    $y = $this->pdf->getY();
3380
-                    $x = $this->pdf->getX();
3381
-                    $dy = $this->_getElementY($lh);
3382
-
3383
-                    // if the next line does  not fit on the page => new page
3384
-                    if ($y + $h>=$this->pdf->getH() - $this->pdf->getbMargin()) {
3385
-                        if (!$this->_isInOverflow && !$this->_isInFooter) {
3386
-                            $this->_setNewPage(null, '', null, $currPos);
3387
-                            $y = $this->pdf->getY();
3388
-                            $x = $this->pdf->getX();
3389
-                            $dy = $this->_getElementY($lh);
3390
-                        }
3391
-                    }
3392
-
3393
-                    // if more than 10000 line => error
3394
-                    $nb++;
3395
-                    if ($nb>10000) {
3396
-                        $txt = ''; foreach ($words as $k => $word) $txt.= ($k ? ' ' : '').$word[0];
3397
-                        throw new HTML2PDF_exception(2, array($txt, $right-$left, $w));
3398
-                    }
3399
-
3400
-                    // new margins for the new line
3401
-                    list($left, $right) = $this->_getMargins($y);
3402
-                }
3403
-            }
3404
-
3405
-            // if we have words after automatic cut, it is because they fit on the line => we write the text
3406
-            if (count($words)) {
3407
-                $txt = ''; foreach ($words as $k => $word) $txt.= ($k ? ' ' : '').$word[0];
3408
-                $w+= $this->pdf->getWordSpacing()*(count($words));
3409
-                $this->pdf->setXY($this->pdf->getX(), $y+$dh+$dy);
3410
-                $this->pdf->Cell(($align=='L' ? $w : $this->parsingCss->value['width']), $h, $txt, 0, 0, $align, $fill, $this->_isInLink);
3411
-                $this->pdf->setXY($this->pdf->getX(), $y);
3412
-                $this->_maxH = max($this->_maxH, $lh);
3413
-                $this->_maxE+= count($words);
3414
-            }
3415
-
3416
-            $maxX = max($maxX, $this->pdf->getX());
3417
-            $maxY = $this->pdf->getY()+$h;
3418
-
3419
-            $this->_maxX = max($this->_maxX, $maxX);
3420
-            $this->_maxY = max($this->_maxY, $maxY);
3421
-
3422
-            return true;
3423
-        }
3424
-
3425
-        /**
3426
-         * tag : BR
3427
-         * mode : OPEN
3428
-         *
3429
-         * @param  array   $param
3430
-         * @param  integer $curr real position in the html parseur (if break line in the write of a text)
3431
-         * @return boolean
3432
-         */
3433
-        protected function _tag_open_BR($param, $curr = null)
3434
-        {
3435
-            if ($this->_isForOneLine) return false;
3436
-
3437
-            $h = max($this->_maxH, $this->parsingCss->getLineHeight());
3438
-
3439
-            if ($this->_maxH==0) $this->_maxY = max($this->_maxY, $this->pdf->getY()+$h);
3440
-
3441
-            $this->_makeBreakLine($h, $curr);
3442
-
3443
-            $this->_maxH = 0;
3444
-            $this->_maxE = 0;
3445
-
3446
-            return true;
3447
-        }
3448
-
3449
-        /**
3450
-         * tag : HR
3451
-         * mode : OPEN
3452
-         *
3453
-         * @param  array $param
3454
-         * @return boolean
3455
-         */
3456
-        protected function _tag_open_HR($param)
3457
-        {
3458
-            if ($this->_isForOneLine) return false;
3459
-            $oldAlign = $this->parsingCss->value['text-align'];
3460
-            $this->parsingCss->value['text-align'] = 'left';
3461
-
3462
-            if ($this->_maxH) $this->_tag_open_BR($param);
3463
-
3464
-            $fontSize = $this->parsingCss->value['font-size'];
3465
-            $this->parsingCss->value['font-size']=$fontSize*0.5; $this->_tag_open_BR($param);
3466
-            $this->parsingCss->value['font-size']=0;
3467
-
3468
-            $param['style']['width'] = '100%';
3469
-
3470
-            $this->parsingCss->save();
3471
-            $this->parsingCss->value['height']=$this->parsingCss->ConvertToMM('1mm');
3472
-
3473
-            $this->parsingCss->analyse('hr', $param);
3474
-            $this->parsingCss->setPosition();
3475
-            $this->parsingCss->fontSet();
3476
-
3477
-            $h = $this->parsingCss->value['height'];
3478
-            if ($h)    $h-= $this->parsingCss->value['border']['t']['width']+$this->parsingCss->value['border']['b']['width'];
3479
-            if ($h<=0) $h = $this->parsingCss->value['border']['t']['width']+$this->parsingCss->value['border']['b']['width'];
3480
-
3481
-            $this->_drawRectangle($this->pdf->getX(), $this->pdf->getY(), $this->parsingCss->value['width'], $h, $this->parsingCss->value['border'], 0, 0, $this->parsingCss->value['background']);
3482
-            $this->_maxH = $h;
3483
-
3484
-            $this->parsingCss->load();
3485
-            $this->parsingCss->fontSet();
3486
-
3487
-            $this->_tag_open_BR($param);
3488
-
3489
-            $this->parsingCss->value['font-size']=$fontSize*0.5; $this->_tag_open_BR($param);
3490
-            $this->parsingCss->value['font-size']=$fontSize;
3491
-
3492
-            $this->parsingCss->value['text-align'] = $oldAlign;
3493
-            $this->_setNewPositionForNewLine();
3494
-
3495
-            return true;
3496
-        }
3497
-
3498
-        /**
3499
-         * tag : B
3500
-         * mode : OPEN
3501
-         *
3502
-         * @param  array $param
3503
-         * @param  string $other
3504
-         * @return boolean
3505
-         */
3506
-        protected function _tag_open_B($param, $other = 'b')
3507
-        {
3508
-            $this->parsingCss->save();
3509
-            $this->parsingCss->value['font-bold'] = true;
3510
-            $this->parsingCss->analyse($other, $param);
3511
-            $this->parsingCss->setPosition();
3512
-            $this->parsingCss->fontSet();
3513
-
3514
-            return true;
3515
-        }
3516
-
3517
-        /**
3518
-         * tag : STRONG
3519
-         * mode : OPEN
3520
-         *
3521
-         * @param  array $param
3522
-         * @return boolean
3523
-         */
3524
-        protected function _tag_open_STRONG($param)
3525
-        {
3526
-            return $this->_tag_open_B($param, 'strong');
3527
-        }
3528
-
3529
-        /**
3530
-         * tag : B
3531
-         * mode : CLOSE
3532
-         *
3533
-         * @param    array $param
3534
-         * @return boolean
3535
-         */
3536
-        protected function _tag_close_B($param)
3537
-        {
3538
-            $this->parsingCss->load();
3539
-            $this->parsingCss->fontSet();
3540
-
3541
-            return true;
3542
-        }
3543
-
3544
-        /**
3545
-         * tag : STRONG
3546
-         * mode : CLOSE
3547
-         *
3548
-         * @param  array $param
3549
-         * @return boolean
3550
-         */
3551
-        protected function _tag_close_STRONG($param)
3552
-        {
3553
-            return $this->_tag_close_B($param);
3554
-        }
3555
-
3556
-        /**
3557
-         * tag : I
3558
-         * mode : OPEN
3559
-         *
3560
-         * @param  array $param
3561
-         * @param  string $other
3562
-         * @return boolean
3563
-         */
3564
-        protected function _tag_open_I($param, $other = 'i')
3565
-        {
3566
-            $this->parsingCss->save();
3567
-            $this->parsingCss->value['font-italic'] = true;
3568
-            $this->parsingCss->analyse($other, $param);
3569
-            $this->parsingCss->setPosition();
3570
-            $this->parsingCss->fontSet();
3571
-
3572
-            return true;
3573
-        }
3574
-
3575
-        /**
3576
-         * tag : ADDRESS
3577
-         * mode : OPEN
3578
-         *
3579
-         * @param  array $param
3580
-         * @return boolean
3581
-         */
3582
-        protected function _tag_open_ADDRESS($param)
3583
-        {
3584
-            return $this->_tag_open_I($param, 'address');
3585
-        }
3586
-
3587
-        /**
3588
-         * tag : CITE
3589
-         * mode : OPEN
3590
-         *
3591
-         * @param  array $param
3592
-         * @return boolean
3593
-         */
3594
-        protected function _tag_open_CITE($param)
3595
-        {
3596
-            return $this->_tag_open_I($param, 'cite');
3597
-        }
3598
-
3599
-        /**
3600
-         * tag : EM
3601
-         * mode : OPEN
3602
-         *
3603
-         * @param  array $param
3604
-         * @return boolean
3605
-         */
3606
-        protected function _tag_open_EM($param)
3607
-        {
3608
-            return $this->_tag_open_I($param, 'em');
3609
-        }
3610
-
3611
-        /**
3612
-         * tag : SAMP
3613
-         * mode : OPEN
3614
-         *
3615
-         * @param  array $param
3616
-         * @return boolean
3617
-         */
3618
-        protected function _tag_open_SAMP($param)
3619
-        {
3620
-            return $this->_tag_open_I($param, 'samp');
3621
-        }
3622
-
3623
-        /**
3624
-         * tag : I
3625
-         * mode : CLOSE
3626
-         *
3627
-         * @param  array $param
3628
-         * @return boolean
3629
-         */
3630
-        protected function _tag_close_I($param)
3631
-        {
3632
-            $this->parsingCss->load();
3633
-            $this->parsingCss->fontSet();
3634
-
3635
-            return true;
3636
-        }
3637
-
3638
-        /**
3639
-         * tag : ADDRESS
3640
-         * mode : CLOSE
3641
-         *
3642
-         * @param  array $param
3643
-         * @return boolean
3644
-         */
3645
-        protected function _tag_close_ADDRESS($param)
3646
-        {
3647
-            return $this->_tag_close_I($param);
3648
-        }
3649
-
3650
-        /**
3651
-         * tag : CITE
3652
-         * mode : CLOSE
3653
-         *
3654
-         * @param  array $param
3655
-         * @return boolean
3656
-         */
3657
-        protected function _tag_close_CITE($param)
3658
-        {
3659
-            return $this->_tag_close_I($param);
3660
-        }
3661
-
3662
-        /**
3663
-         * tag : EM
3664
-         * mode : CLOSE
3665
-         *
3666
-         * @param  array $param
3667
-         * @return boolean
3668
-         */
3669
-        protected function _tag_close_EM($param)
3670
-        {
3671
-            return $this->_tag_close_I($param);
3672
-        }
3673
-
3674
-        /**
3675
-         * tag : SAMP
3676
-         * mode : CLOSE
3677
-         *
3678
-         * @param  array $param
3679
-         * @return boolean
3680
-         */
3681
-        protected function _tag_close_SAMP($param)
3682
-        {
3683
-            return $this->_tag_close_I($param);
3684
-        }
3685
-
3686
-        /**
3687
-         * tag : S
3688
-         * mode : OPEN
3689
-         *
3690
-         * @param  array $param
3691
-         * @param  string $other
3692
-         * @return boolean
3693
-         */
3694
-        protected function _tag_open_S($param, $other = 's')
3695
-        {
3696
-            $this->parsingCss->save();
3697
-            $this->parsingCss->value['font-linethrough'] = true;
3698
-            $this->parsingCss->analyse($other, $param);
3699
-            $this->parsingCss->setPosition();
3700
-            $this->parsingCss->fontSet();
3701
-
3702
-            return true;
3703
-        }
3704
-
3705
-        /**
3706
-         * tag : DEL
3707
-         * mode : OPEN
3708
-         *
3709
-         * @param  array $param
3710
-         * @return boolean
3711
-         */
3712
-        protected function _tag_open_DEL($param)
3713
-        {
3714
-            return $this->_tag_open_S($param, 'del');
3715
-        }
3716
-
3717
-        /**
3718
-         * tag : S
3719
-         * mode : CLOSE
3720
-         *
3721
-         * @param    array $param
3722
-         * @return boolean
3723
-         */
3724
-        protected function _tag_close_S($param)
3725
-        {
3726
-            $this->parsingCss->load();
3727
-            $this->parsingCss->fontSet();
3728
-
3729
-            return true;
3730
-        }
3731
-
3732
-        /**
3733
-         * tag : DEL
3734
-         * mode : CLOSE
3735
-         *
3736
-         * @param  array $param
3737
-         * @return boolean
3738
-         */
3739
-        protected function _tag_close_DEL($param)
3740
-        {
3741
-            return $this->_tag_close_S($param);
3742
-        }
3743
-
3744
-        /**
3745
-         * tag : U
3746
-         * mode : OPEN
3747
-         *
3748
-         * @param  array $param
3749
-         * @param  string $other
3750
-         * @return boolean
3751
-         */
3752
-        protected function _tag_open_U($param, $other='u')
3753
-        {
3754
-            $this->parsingCss->save();
3755
-            $this->parsingCss->value['font-underline'] = true;
3756
-            $this->parsingCss->analyse($other, $param);
3757
-            $this->parsingCss->setPosition();
3758
-            $this->parsingCss->fontSet();
3759
-
3760
-            return true;
3761
-        }
3762
-
3763
-        /**
3764
-         * tag : INS
3765
-         * mode : OPEN
3766
-         *
3767
-         * @param  array $param
3768
-         * @return boolean
3769
-         */
3770
-        protected function _tag_open_INS($param)
3771
-        {
3772
-            return $this->_tag_open_U($param, 'ins');
3773
-        }
3774
-
3775
-        /**
3776
-         * tag : U
3777
-         * mode : CLOSE
3778
-         *
3779
-         * @param    array $param
3780
-         * @return boolean
3781
-         */
3782
-        protected function _tag_close_U($param)
3783
-        {
3784
-            $this->parsingCss->load();
3785
-            $this->parsingCss->fontSet();
3786
-
3787
-            return true;
3788
-        }
3789
-
3790
-        /**
3791
-         * tag : INS
3792
-         * mode : CLOSE
3793
-         *
3794
-         * @param  array $param
3795
-         * @return boolean
3796
-         */
3797
-        protected function _tag_close_INS($param)
3798
-        {
3799
-            return $this->_tag_close_U($param);
3800
-        }
3801
-
3802
-        /**
3803
-         * tag : A
3804
-         * mode : OPEN
3805
-         *
3806
-         * @param  array $param
3807
-         * @return boolean
3808
-         */
3809
-        protected function _tag_open_A($param)
3810
-        {
3811
-            $this->_isInLink = str_replace('&amp;', '&', isset($param['href']) ? $param['href'] : '');
3812
-
3813
-            if (isset($param['name'])) {
3814
-                $name =     $param['name'];
3815
-                if (!isset($this->_lstAnchor[$name])) $this->_lstAnchor[$name] = array($this->pdf->AddLink(), false);
3816
-
3817
-                if (!$this->_lstAnchor[$name][1]) {
3818
-                    $this->_lstAnchor[$name][1] = true;
3819
-                    $this->pdf->SetLink($this->_lstAnchor[$name][0], -1, -1);
3820
-                }
3821
-            }
3822
-
3823
-            if (preg_match('/^#([^#]+)$/isU', $this->_isInLink, $match)) {
3824
-                $name = $match[1];
3825
-                if (!isset($this->_lstAnchor[$name])) $this->_lstAnchor[$name] = array($this->pdf->AddLink(), false);
3826
-
3827
-                $this->_isInLink = $this->_lstAnchor[$name][0];
3828
-            }
3829
-
3830
-            $this->parsingCss->save();
3831
-            $this->parsingCss->value['font-underline'] = true;
3832
-            $this->parsingCss->value['color'] = array(20, 20, 250);
3833
-            $this->parsingCss->analyse('a', $param);
3834
-            $this->parsingCss->setPosition();
3835
-            $this->parsingCss->fontSet();
3836
-
3837
-            return true;
3838
-        }
3839
-
3840
-        /**
3841
-         * tag : A
3842
-         * mode : CLOSE
3843
-         *
3844
-         * @param  array $param
3845
-         * @return boolean
3846
-         */
3847
-        protected function _tag_close_A($param)
3848
-        {
3849
-            $this->_isInLink    = '';
3850
-            $this->parsingCss->load();
3851
-            $this->parsingCss->fontSet();
3852
-
3853
-            return true;
3854
-        }
3855
-
3856
-        /**
3857
-         * tag : H1
3858
-         * mode : OPEN
3859
-         *
3860
-         * @param  array $param
3861
-         * @param  string $other
3862
-         * @return boolean
3863
-         */
3864
-        protected function _tag_open_H1($param, $other = 'h1')
3865
-        {
3866
-            if ($this->_isForOneLine) return false;
3867
-
3868
-            if ($this->_maxH) $this->_tag_open_BR(array());
3869
-            $this->parsingCss->save();
3870
-            $this->parsingCss->value['font-bold'] = true;
3871
-
3872
-            $size = array('h1' => '28px', 'h2' => '24px', 'h3' => '20px', 'h4' => '16px', 'h5' => '12px', 'h6' => '9px');
3873
-            $this->parsingCss->value['margin']['l'] = 0;
3874
-            $this->parsingCss->value['margin']['r'] = 0;
3875
-            $this->parsingCss->value['margin']['t'] = $this->parsingCss->ConvertToMM('16px');
3876
-            $this->parsingCss->value['margin']['b'] = $this->parsingCss->ConvertToMM('16px');
3877
-            $this->parsingCss->value['font-size'] = $this->parsingCss->ConvertToMM($size[$other]);
3878
-
3879
-            $this->parsingCss->analyse($other, $param);
3880
-            $this->parsingCss->setPosition();
3881
-            $this->parsingCss->fontSet();
3882
-            $this->_setNewPositionForNewLine();
3883
-
3884
-            return true;
3885
-        }
3886
-
3887
-        /**
3888
-         * tag : H2
3889
-         * mode : OPEN
3890
-         *
3891
-         * @param  array $param
3892
-         * @return boolean
3893
-         */
3894
-        protected function _tag_open_H2($param)
3895
-        {
3896
-            return $this->_tag_open_H1($param, 'h2');
3897
-        }
3898
-
3899
-        /**
3900
-         * tag : H3
3901
-         * mode : OPEN
3902
-         *
3903
-         * @param  array $param
3904
-         * @return boolean
3905
-         */
3906
-        protected function _tag_open_H3($param)
3907
-        {
3908
-            return $this->_tag_open_H1($param, 'h3');
3909
-        }
3910
-
3911
-        /**
3912
-         * tag : H4
3913
-         * mode : OPEN
3914
-         *
3915
-         * @param  array $param
3916
-         * @return boolean
3917
-         */
3918
-        protected function _tag_open_H4($param)
3919
-        {
3920
-            return $this->_tag_open_H1($param, 'h4');
3921
-        }
3922
-
3923
-        /**
3924
-         * tag : H5
3925
-         * mode : OPEN
3926
-         *
3927
-         * @param  array $param
3928
-         * @return boolean
3929
-         */
3930
-        protected function _tag_open_H5($param)
3931
-        {
3932
-            return $this->_tag_open_H1($param, 'h5');
3933
-        }
3934
-
3935
-        /**
3936
-         * tag : H6
3937
-         * mode : OPEN
3938
-         *
3939
-         * @param  array $param
3940
-         * @return boolean
3941
-         */
3942
-        protected function _tag_open_H6($param)
3943
-        {
3944
-            return $this->_tag_open_H1($param, 'h6');
3945
-        }
3946
-
3947
-        /**
3948
-         * tag : H1
3949
-         * mode : CLOSE
3950
-         *
3951
-         * @param  array $param
3952
-         * @return boolean
3953
-         */
3954
-        protected function _tag_close_H1($param)
3955
-        {
3956
-            if ($this->_isForOneLine) return false;
3957
-
3958
-            $this->_maxH+= $this->parsingCss->value['margin']['b'];
3959
-            $h = max($this->_maxH, $this->parsingCss->getLineHeight());
3960
-
3961
-            $this->parsingCss->load();
3962
-            $this->parsingCss->fontSet();
3963
-
3964
-            $this->_makeBreakLine($h);
3965
-            $this->_maxH = 0;
3966
-
3967
-            $this->_maxY = max($this->_maxY, $this->pdf->getY());
3968
-
3969
-            return true;
3970
-        }
3971
-
3972
-        /**
3973
-         * tag : H2
3974
-         * mode : CLOSE
3975
-         *
3976
-         * @param  array $param
3977
-         * @return boolean
3978
-         */
3979
-        protected function _tag_close_H2($param)
3980
-        {
3981
-            return $this->_tag_close_H1($param);
3982
-        }
3983
-
3984
-        /**
3985
-         * tag : H3
3986
-         * mode : CLOSE
3987
-         *
3988
-         * @param  array $param
3989
-         * @return boolean
3990
-         */
3991
-        protected function _tag_close_H3($param)
3992
-        {
3993
-            return $this->_tag_close_H1($param);
3994
-        }
3995
-
3996
-        /**
3997
-         * tag : H4
3998
-         * mode : CLOSE
3999
-         *
4000
-         * @param  array $param
4001
-         * @return boolean
4002
-         */
4003
-        protected function _tag_close_H4($param)
4004
-        {
4005
-            return $this->_tag_close_H1($param);
4006
-        }
4007
-
4008
-        /**
4009
-         * tag : H5
4010
-         * mode : CLOSE
4011
-         *
4012
-         * @param  array $param
4013
-         * @return boolean
4014
-         */
4015
-        protected function _tag_close_H5($param)
4016
-        {
4017
-            return $this->_tag_close_H1($param);
4018
-        }
4019
-
4020
-        /**
4021
-         * tag : H6
4022
-         * mode : CLOSE
4023
-         *
4024
-         * @param  array $param
4025
-         * @return boolean
4026
-         */
4027
-        protected function _tag_close_H6($param)
4028
-        {
4029
-            return $this->_tag_close_H1($param);
4030
-        }
4031
-
4032
-        /**
4033
-         * tag : SPAN
4034
-         * mode : OPEN
4035
-         *
4036
-         * @param  array $param
4037
-         * @param  string $other
4038
-         * @return boolean
4039
-         */
4040
-        protected function _tag_open_SPAN($param, $other = 'span')
4041
-        {
4042
-            $this->parsingCss->save();
4043
-            $this->parsingCss->analyse($other, $param);
4044
-            $this->parsingCss->setPosition();
4045
-            $this->parsingCss->fontSet();
4046
-
4047
-            return true;
4048
-        }
4049
-
4050
-        /**
4051
-         * tag : FONT
4052
-         * mode : OPEN
4053
-         *
4054
-         * @param  array $param
4055
-         * @return boolean
4056
-         */
4057
-        protected function _tag_open_FONT($param)
4058
-        {
4059
-            return $this->_tag_open_SPAN($param, 'font');
4060
-        }
4061
-
4062
-        /**
4063
-         * tag : LABEL
4064
-         * mode : OPEN
4065
-         *
4066
-         * @param  array $param
4067
-         * @return boolean
4068
-         */
4069
-        protected function _tag_open_LABEL($param)
4070
-        {
4071
-            return $this->_tag_open_SPAN($param, 'label');
4072
-        }
4073
-
4074
-        /**
4075
-         * tag : SPAN
4076
-         * mode : CLOSE
4077
-         *
4078
-         * @param  array $param
4079
-         * @return boolean
4080
-         */
4081
-        protected function _tag_close_SPAN($param)
4082
-        {
4083
-            $this->parsingCss->restorePosition();
4084
-            $this->parsingCss->load();
4085
-            $this->parsingCss->fontSet();
4086
-
4087
-            return true;
4088
-        }
4089
-
4090
-        /**
4091
-         * tag : FONT
4092
-         * mode : CLOSE
4093
-         *
4094
-         * @param  array $param
4095
-         * @return boolean
4096
-         */
4097
-        protected function _tag_close_FONT($param)
4098
-        {
4099
-            return $this->_tag_close_SPAN($param);
4100
-        }
4101
-
4102
-        /**
4103
-         * tag : LABEL
4104
-         * mode : CLOSE
4105
-         *
4106
-         * @param  array $param
4107
-         * @return boolean
4108
-         */
4109
-        protected function _tag_close_LABEL($param)
4110
-        {
4111
-            return $this->_tag_close_SPAN($param);
4112
-        }
4113
-
4114
-        /**
4115
-         * tag : P
4116
-         * mode : OPEN
4117
-         *
4118
-         * @param    array $param
4119
-         * @return boolean
4120
-         */
4121
-        protected function _tag_open_P($param)
4122
-        {
4123
-            if ($this->_isForOneLine) return false;
4124
-
4125
-            if (!in_array($this->_previousCall, array('_tag_close_P', '_tag_close_UL'))) {
4126
-                if ($this->_maxH) $this->_tag_open_BR(array());
4127
-            }
4128
-
4129
-            $this->parsingCss->save();
4130
-            $this->parsingCss->analyse('p', $param);
4131
-            $this->parsingCss->setPosition();
4132
-            $this->parsingCss->fontSet();
4133
-
4134
-             // cancel the effects of the setPosition
4135
-            $this->pdf->setXY($this->pdf->getX()-$this->parsingCss->value['margin']['l'], $this->pdf->getY()-$this->parsingCss->value['margin']['t']);
4136
-
4137
-            list($mL, $mR) = $this->_getMargins($this->pdf->getY());
4138
-            $mR = $this->pdf->getW()-$mR;
4139
-            $mL+= $this->parsingCss->value['margin']['l']+$this->parsingCss->value['padding']['l'];
4140
-            $mR+= $this->parsingCss->value['margin']['r']+$this->parsingCss->value['padding']['r'];
4141
-            $this->_saveMargin($mL, 0, $mR);
4142
-
4143
-            if ($this->parsingCss->value['text-indent']>0) {
4144
-                $y = $this->pdf->getY()+$this->parsingCss->value['margin']['t']+$this->parsingCss->value['padding']['t'];
4145
-                $this->_pageMarges[floor($y*100)] = array($mL+$this->parsingCss->value['text-indent'], $this->pdf->getW()-$mR);
4146
-                $y+= $this->parsingCss->getLineHeight()*0.1;
4147
-                $this->_pageMarges[floor($y*100)] = array($mL, $this->pdf->getW()-$mR);
4148
-            }
4149
-            $this->_makeBreakLine($this->parsingCss->value['margin']['t']+$this->parsingCss->value['padding']['t']);
4150
-            $this->_isInParagraph = array($mL, $mR);
4151
-            return true;
4152
-        }
4153
-
4154
-        /**
4155
-         * tag : P
4156
-         * mode : CLOSE
4157
-         *
4158
-         * @param  array $param
4159
-         * @return boolean
4160
-         */
4161
-        protected function _tag_close_P($param)
4162
-        {
4163
-            if ($this->_isForOneLine) return false;
4164
-
4165
-            if ($this->_maxH) $this->_tag_open_BR(array());
4166
-            $this->_isInParagraph = false;
4167
-            $this->_loadMargin();
4168
-            $h = $this->parsingCss->value['margin']['b']+$this->parsingCss->value['padding']['b'];
4169
-
4170
-            $this->parsingCss->load();
4171
-            $this->parsingCss->fontSet();
4172
-            $this->_makeBreakLine($h);
4173
-
4174
-            return true;
4175
-        }
4176
-
4177
-        /**
4178
-         * tag : PRE
4179
-         * mode : OPEN
4180
-         *
4181
-         * @param  array $param
4182
-         * @param  string $other
4183
-         * @return boolean
4184
-         */
4185
-        protected function _tag_open_PRE($param, $other = 'pre')
4186
-        {
4187
-            if ($other=='pre' && $this->_maxH) $this->_tag_open_BR(array());
4188
-
4189
-            $this->parsingCss->save();
4190
-            $this->parsingCss->value['font-family'] = 'courier';
4191
-            $this->parsingCss->analyse($other, $param);
4192
-            $this->parsingCss->setPosition();
4193
-            $this->parsingCss->fontSet();
4194
-
4195
-            if ($other=='pre') return $this->_tag_open_DIV($param, $other);
4196
-
4197
-            return true;
4198
-        }
4199
-
4200
-        /**
4201
-         * tag : CODE
4202
-         * mode : OPEN
4203
-         *
4204
-         * @param  array $param
4205
-         * @param  string $other
4206
-         * @return boolean
4207
-         */
4208
-        protected function _tag_open_CODE($param)
4209
-        {
4210
-            return $this->_tag_open_PRE($param, 'code');
4211
-        }
4212
-
4213
-        /**
4214
-         * tag : PRE
4215
-         * mode : CLOSE
4216
-         *
4217
-         * @param  array $param
4218
-         * @param  string $other
4219
-         * @return boolean
4220
-         */
4221
-        protected function _tag_close_PRE($param, $other = 'pre')
4222
-        {
4223
-            if ($other=='pre') {
4224
-                if ($this->_isForOneLine) return false;
4225
-
4226
-                $this->_tag_close_DIV($param, $other);
4227
-                $this->_tag_open_BR(array());
4228
-            }
4229
-            $this->parsingCss->load();
4230
-            $this->parsingCss->fontSet();
4231
-
4232
-            return true;
4233
-        }
4234
-
4235
-        /**
4236
-         * tag : CODE
4237
-         * mode : CLOSE
4238
-         *
4239
-         * @param  array $param
4240
-         * @return boolean
4241
-         */
4242
-        protected function _tag_close_CODE($param)
4243
-        {
4244
-            return $this->_tag_close_PRE($param, 'code');
4245
-        }
4246
-
4247
-        /**
4248
-         * tag : BIG
4249
-         * mode : OPEN
4250
-         *
4251
-         * @param    array $param
4252
-         * @return boolean
4253
-         */
4254
-        protected function _tag_open_BIG($param)
4255
-        {
4256
-            $this->parsingCss->save();
4257
-            $this->parsingCss->value['mini-decal']-= $this->parsingCss->value['mini-size']*0.12;
4258
-            $this->parsingCss->value['mini-size'] *= 1.2;
4259
-            $this->parsingCss->analyse('big', $param);
4260
-            $this->parsingCss->setPosition();
4261
-            $this->parsingCss->fontSet();
4262
-            return true;
4263
-        }
4264
-
4265
-        /**
4266
-         * tag : BIG
4267
-         * mode : CLOSE
4268
-         *
4269
-         * @param    array $param
4270
-         * @return boolean
4271
-         */
4272
-        protected function _tag_close_BIG($param)
4273
-        {
4274
-            $this->parsingCss->load();
4275
-            $this->parsingCss->fontSet();
4276
-
4277
-            return true;
4278
-        }
4279
-
4280
-        /**
4281
-         * tag : SMALL
4282
-         * mode : OPEN
4283
-         *
4284
-         * @param    array $param
4285
-         * @return boolean
4286
-         */
4287
-        protected function _tag_open_SMALL($param)
4288
-        {
4289
-            $this->parsingCss->save();
4290
-            $this->parsingCss->value['mini-decal']+= $this->parsingCss->value['mini-size']*0.05;
4291
-            $this->parsingCss->value['mini-size'] *= 0.82;
4292
-            $this->parsingCss->analyse('small', $param);
4293
-            $this->parsingCss->setPosition();
4294
-            $this->parsingCss->fontSet();
4295
-            return true;
4296
-        }
4297
-
4298
-        /**
4299
-         * tag : SMALL
4300
-         * mode : CLOSE
4301
-         *
4302
-         * @param    array $param
4303
-         * @return boolean
4304
-         */
4305
-        protected function _tag_close_SMALL($param)
4306
-        {
4307
-            $this->parsingCss->load();
4308
-            $this->parsingCss->fontSet();
4309
-
4310
-            return true;
4311
-        }
4312
-
4313
-        /**
4314
-         * tag : SUP
4315
-         * mode : OPEN
4316
-         *
4317
-         * @param    array $param
4318
-         * @return boolean
4319
-         */
4320
-        protected function _tag_open_SUP($param)
4321
-        {
4322
-            $this->parsingCss->save();
4323
-            $this->parsingCss->value['mini-decal']-= $this->parsingCss->value['mini-size']*0.15;
4324
-            $this->parsingCss->value['mini-size'] *= 0.75;
4325
-            $this->parsingCss->analyse('sup', $param);
4326
-            $this->parsingCss->setPosition();
4327
-            $this->parsingCss->fontSet();
4328
-
4329
-            return true;
4330
-        }
4331
-
4332
-        /**
4333
-         * tag : SUP
4334
-         * mode : CLOSE
4335
-         *
4336
-         * @param    array $param
4337
-         * @return boolean
4338
-         */
4339
-        protected function _tag_close_SUP($param)
4340
-        {
4341
-            $this->parsingCss->load();
4342
-            $this->parsingCss->fontSet();
4343
-
4344
-            return true;
4345
-        }
4346
-
4347
-        /**
4348
-         * tag : SUB
4349
-         * mode : OPEN
4350
-         *
4351
-         * @param    array $param
4352
-         * @return boolean
4353
-         */
4354
-        protected function _tag_open_SUB($param)
4355
-        {
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('sub', $param);
4360
-            $this->parsingCss->setPosition();
4361
-            $this->parsingCss->fontSet();
4362
-            return true;
4363
-        }
4364
-
4365
-        /**
4366
-         * tag : SUB
4367
-         * mode : CLOSE
4368
-         *
4369
-         * @param    array $param
4370
-         * @return boolean
4371
-         */
4372
-        protected function _tag_close_SUB($param)
4373
-        {
4374
-            $this->parsingCss->load();
4375
-            $this->parsingCss->fontSet();
4376
-
4377
-            return true;
4378
-        }
4379
-
4380
-        /**
4381
-         * tag : UL
4382
-         * mode : OPEN
4383
-         *
4384
-         * @param  array $param
4385
-         * @param  string $other
4386
-         * @return boolean
4387
-         */
4388
-        protected function _tag_open_UL($param, $other = 'ul')
4389
-        {
4390
-            if ($this->_isForOneLine) return false;
4391
-
4392
-            if (!in_array($this->_previousCall, array('_tag_close_P', '_tag_close_UL'))) {
4393
-                if ($this->_maxH) $this->_tag_open_BR(array());
4394
-                if (!count($this->_defList)) $this->_tag_open_BR(array());
4395
-            }
4396
-
4397
-            if (!isset($param['style']['width'])) $param['allwidth'] = true;
4398
-            $param['cellspacing'] = 0;
4399
-
4400
-            // a list is like a table
4401
-            $this->_tag_open_TABLE($param, $other);
4402
-
4403
-            // add a level of list
4404
-            $this->_listeAddLevel($other, $this->parsingCss->value['list-style-type'], $this->parsingCss->value['list-style-image']);
4405
-
4406
-            return true;
4407
-        }
4408
-
4409
-        /**
4410
-         * tag : OL
4411
-         * mode : OPEN
4412
-         *
4413
-         * @param  array $param
4414
-         * @return boolean
4415
-         */
4416
-        protected function _tag_open_OL($param)
4417
-        {
4418
-            return $this->_tag_open_UL($param, 'ol');
4419
-        }
4420
-
4421
-        /**
4422
-         * tag : UL
4423
-         * mode : CLOSE
4424
-         *
4425
-         * @param  array $param
4426
-         * @return boolean
4427
-         */
4428
-        protected function _tag_close_UL($param)
4429
-        {
4430
-            if ($this->_isForOneLine) return false;
4431
-
4432
-            $this->_tag_close_TABLE($param);
4433
-
4434
-            $this->_listeDelLevel();
4435
-
4436
-            if (!$this->_subPart) {
4437
-                if (!count($this->_defList)) $this->_tag_open_BR(array());
4438
-            }
4439
-
4440
-            return true;
4441
-        }
4442
-
4443
-        /**
4444
-         * tag : OL
4445
-         * mode : CLOSE
4446
-         *
4447
-         * @param  array $param
4448
-         * @return boolean
4449
-         */
4450
-        protected function _tag_close_OL($param)
4451
-        {
4452
-            return $this->_tag_close_UL($param);
4453
-        }
4454
-
4455
-        /**
4456
-         * tag : LI
4457
-         * mode : OPEN
4458
-         *
4459
-         * @param  array $param
4460
-         * @return boolean
4461
-         */
4462
-        protected function _tag_open_LI($param)
4463
-        {
4464
-            if ($this->_isForOneLine) return false;
4465
-
4466
-            $this->_listeAddLi();
4467
-
4468
-            if (!isset($param['style']['width'])) $param['style']['width'] = '100%';
4469
-
4470
-            $paramPUCE = $param;
4471
-
4472
-            $inf = $this->_listeGetLi();
4473
-            if ($inf[0]) {
4474
-                $paramPUCE['style']['font-family']     = $inf[0];
4475
-                $paramPUCE['style']['text-align']      = 'li_right';
4476
-                $paramPUCE['style']['vertical-align']  = 'top';
4477
-                $paramPUCE['style']['width']           = $this->_listeGetWidth();
4478
-                $paramPUCE['style']['padding-right']   = $this->_listeGetPadding();
4479
-                $paramPUCE['txt'] = $inf[2];
4480
-            } else {
4481
-                $paramPUCE['style']['text-align']      = 'li_right';
4482
-                $paramPUCE['style']['vertical-align']  = 'top';
4483
-                $paramPUCE['style']['width']           = $this->_listeGetWidth();
4484
-                $paramPUCE['style']['padding-right']   = $this->_listeGetPadding();
4485
-                $paramPUCE['src'] = $inf[2];
4486
-                $paramPUCE['sub_li'] = true;
4487
-            }
4488
-
4489
-            $this->_tag_open_TR($param, 'li');
4490
-
4491
-            $this->parsingCss->save();
4492
-
4493
-            // if small LI
4494
-            if ($inf[1]) {
4495
-                $this->parsingCss->value['mini-decal']+= $this->parsingCss->value['mini-size']*0.045;
4496
-                $this->parsingCss->value['mini-size'] *= 0.75;
4497
-            }
4498
-
4499
-            // if we are in a sub html => prepare. Else : display
4500
-            if ($this->_subPart) {
4501
-                // TD for the puce
4502
-                $tmpPos = $this->_tempPos;
4503
-                $tmpLst1 = $this->parsingHtml->code[$tmpPos+1];
4504
-                $tmpLst2 = $this->parsingHtml->code[$tmpPos+2];
4505
-                $this->parsingHtml->code[$tmpPos+1] = array();
4506
-                $this->parsingHtml->code[$tmpPos+1]['name']    = (isset($paramPUCE['src'])) ? 'img' : 'write';
4507
-                $this->parsingHtml->code[$tmpPos+1]['param']    = $paramPUCE; unset($this->parsingHtml->code[$tmpPos+1]['param']['style']['width']);
4508
-                $this->parsingHtml->code[$tmpPos+1]['close']    = 0;
4509
-                $this->parsingHtml->code[$tmpPos+2] = array();
4510
-                $this->parsingHtml->code[$tmpPos+2]['name']    = 'li';
4511
-                $this->parsingHtml->code[$tmpPos+2]['param']    = $paramPUCE;
4512
-                $this->parsingHtml->code[$tmpPos+2]['close']    = 1;
4513
-                $this->_tag_open_TD($paramPUCE, 'li_sub');
4514
-                $this->_tag_close_TD($param);
4515
-                $this->_tempPos = $tmpPos;
4516
-                $this->parsingHtml->code[$tmpPos+1] = $tmpLst1;
4517
-                $this->parsingHtml->code[$tmpPos+2] = $tmpLst2;
4518
-            } else {
4519
-                // TD for the puce
4520
-                $this->_tag_open_TD($paramPUCE, 'li_sub');
4521
-                unset($paramPUCE['style']['width']);
4522
-                if (isset($paramPUCE['src']))    $this->_tag_open_IMG($paramPUCE);
4523
-                else                            $this->_tag_open_WRITE($paramPUCE);
4524
-                $this->_tag_close_TD($paramPUCE);
4525
-            }
4526
-            $this->parsingCss->load();
4527
-
4528
-
4529
-            // TD for the content
4530
-            $this->_tag_open_TD($param, 'li');
4531
-
4532
-            return true;
4533
-        }
4534
-
4535
-        /**
4536
-         * tag : LI
4537
-         * mode : CLOSE
4538
-         *
4539
-         * @param  array $param
4540
-         * @return boolean
4541
-         */
4542
-        protected function _tag_close_LI($param)
4543
-        {
4544
-            if ($this->_isForOneLine) return false;
4545
-
4546
-            $this->_tag_close_TD($param);
4547
-
4548
-            $this->_tag_close_TR($param);
4549
-
4550
-            return true;
4551
-        }
4552
-
4553
-        /**
4554
-         * tag : TBODY
4555
-         * mode : OPEN
4556
-         *
4557
-         * @param  array $param
4558
-         * @return boolean
4559
-         */
4560
-        protected function _tag_open_TBODY($param)
4561
-        {
4562
-            if ($this->_isForOneLine) return false;
4563
-
4564
-            $this->parsingCss->save();
4565
-            $this->parsingCss->analyse('tbody', $param);
4566
-            $this->parsingCss->setPosition();
4567
-            $this->parsingCss->fontSet();
4568
-
4569
-            return true;
4570
-        }
4571
-
4572
-        /**
4573
-         * tag : TBODY
4574
-         * mode : CLOSE
4575
-         *
4576
-         * @param  array $param
4577
-         * @return boolean
4578
-         */
4579
-        protected function _tag_close_TBODY($param)
4580
-        {
4581
-            if ($this->_isForOneLine) return false;
4582
-
4583
-            $this->parsingCss->load();
4584
-            $this->parsingCss->fontSet();
4585
-
4586
-            return true;
4587
-        }
4588
-
4589
-        /**
4590
-         * tag : THEAD
4591
-         * mode : OPEN
4592
-         *
4593
-         * @param  array $param
4594
-         * @return boolean
4595
-         */
4596
-        protected function _tag_open_THEAD($param)
4597
-        {
4598
-            if ($this->_isForOneLine) return false;
4599
-
4600
-            $this->parsingCss->save();
4601
-            $this->parsingCss->analyse('thead', $param);
4602
-            $this->parsingCss->setPosition();
4603
-            $this->parsingCss->fontSet();
4604
-
4605
-            // if we are in a sub part, save the number of the first TR in the thead
4606
-            if ($this->_subPart) {
4607
-                HTML2PDF::$_tables[$param['num']]['thead']['tr'][0] = HTML2PDF::$_tables[$param['num']]['tr_curr'];
4608
-                HTML2PDF::$_tables[$param['num']]['thead']['code'] = array();
4609
-                for ($pos=$this->_tempPos; $pos<count($this->parsingHtml->code); $pos++) {
4610
-                    $action = $this->parsingHtml->code[$pos];
4611
-                    if (strtolower($action['name'])=='thead') $action['name'] = 'thead_sub';
4612
-                    HTML2PDF::$_tables[$param['num']]['thead']['code'][] = $action;
4613
-                    if (strtolower($action['name'])=='thead_sub' && $action['close']) break;
4614
-                }
4615
-            } else {
4616
-                $level = $this->parsingHtml->getLevel($this->_parsePos);
4617
-                $this->_parsePos+= count($level);
4618
-                HTML2PDF::$_tables[$param['num']]['tr_curr']+= count(HTML2PDF::$_tables[$param['num']]['thead']['tr']);
4619
-            }
4620
-
4621
-            return true;
4622
-        }
4623
-
4624
-        /**
4625
-         * tag : THEAD
4626
-         * mode : CLOSE
4627
-         *
4628
-         * @param  array $param
4629
-         * @return boolean
4630
-         */
4631
-        protected function _tag_close_THEAD($param)
4632
-        {
4633
-            if ($this->_isForOneLine) return false;
4634
-
4635
-            $this->parsingCss->load();
4636
-            $this->parsingCss->fontSet();
4637
-
4638
-            // if we are in a sub HTM, construct the list of the TR in the thead
4639
-            if ($this->_subPart) {
4640
-                $min = HTML2PDF::$_tables[$param['num']]['thead']['tr'][0];
4641
-                $max = HTML2PDF::$_tables[$param['num']]['tr_curr']-1;
4642
-                HTML2PDF::$_tables[$param['num']]['thead']['tr'] = range($min, $max);
4643
-            }
4644
-
4645
-            return true;
4646
-        }
4647
-
4648
-        /**
4649
-         * tag : TFOOT
4650
-         * mode : OPEN
4651
-         *
4652
-         * @param  array $param
4653
-         * @return boolean
4654
-         */
4655
-        protected function _tag_open_TFOOT($param)
4656
-        {
4657
-            if ($this->_isForOneLine) return false;
4658
-
4659
-            $this->parsingCss->save();
4660
-            $this->parsingCss->analyse('tfoot', $param);
4661
-            $this->parsingCss->setPosition();
4662
-            $this->parsingCss->fontSet();
4663
-
4664
-            // if we are in a sub part, save the number of the first TR in the tfoot
4665
-            if ($this->_subPart) {
4666
-                HTML2PDF::$_tables[$param['num']]['tfoot']['tr'][0] = HTML2PDF::$_tables[$param['num']]['tr_curr'];
4667
-                HTML2PDF::$_tables[$param['num']]['tfoot']['code'] = array();
4668
-                for ($pos=$this->_tempPos; $pos<count($this->parsingHtml->code); $pos++) {
4669
-                    $action = $this->parsingHtml->code[$pos];
4670
-                    if (strtolower($action['name'])=='tfoot') $action['name'] = 'tfoot_sub';
4671
-                    HTML2PDF::$_tables[$param['num']]['tfoot']['code'][] = $action;
4672
-                    if (strtolower($action['name'])=='tfoot_sub' && $action['close']) break;
4673
-                }
4674
-            } else {
4675
-                $level = $this->parsingHtml->getLevel($this->_parsePos);
4676
-                $this->_parsePos+= count($level);
4677
-                HTML2PDF::$_tables[$param['num']]['tr_curr']+= count(HTML2PDF::$_tables[$param['num']]['tfoot']['tr']);
4678
-            }
4679
-
4680
-            return true;
4681
-        }
4682
-
4683
-        /**
4684
-         * tag : TFOOT
4685
-         * mode : CLOSE
4686
-         *
4687
-         * @param  array $param
4688
-         * @return boolean
4689
-         */
4690
-        protected function _tag_close_TFOOT($param)
4691
-        {
4692
-            if ($this->_isForOneLine) return false;
4693
-
4694
-            $this->parsingCss->load();
4695
-            $this->parsingCss->fontSet();
4696
-
4697
-            // if we are in a sub HTM, construct the list of the TR in the tfoot
4698
-            if ($this->_subPart) {
4699
-                $min = HTML2PDF::$_tables[$param['num']]['tfoot']['tr'][0];
4700
-                $max = HTML2PDF::$_tables[$param['num']]['tr_curr']-1;
4701
-                HTML2PDF::$_tables[$param['num']]['tfoot']['tr'] = range($min, $max);
4702
-            }
4703
-
4704
-            return true;
4705
-        }
4706
-
4707
-        /**
4708
-         * It is not a real TAG, does not use it !
4709
-         *
4710
-         * @param  array $param
4711
-         * @return boolean
4712
-         */
4713
-        protected function _tag_open_THEAD_SUB($param)
4714
-        {
4715
-            if ($this->_isForOneLine) return false;
4716
-
4717
-            $this->parsingCss->save();
4718
-            $this->parsingCss->analyse('thead', $param);
4719
-            $this->parsingCss->setPosition();
4720
-            $this->parsingCss->fontSet();
4721
-
4722
-            return true;
4723
-        }
4724
-
4725
-        /**
4726
-         * It is not a real TAG, does not use it !
4727
-         *
4728
-         * @param  array $param
4729
-         * @return boolean
4730
-         */
4731
-        protected function _tag_close_THEAD_SUB($param)
4732
-        {
4733
-            if ($this->_isForOneLine) return false;
4734
-
4735
-            $this->parsingCss->load();
4736
-            $this->parsingCss->fontSet();
4737
-
4738
-            return true;
4739
-        }
4740
-
4741
-        /**
4742
-         * It is not a real TAG, does not use it !
4743
-         *
4744
-         * @param    array $param
4745
-         * @return boolean
4746
-         */
4747
-        protected function _tag_open_TFOOT_SUB($param)
4748
-        {
4749
-            if ($this->_isForOneLine) return false;
4750
-
4751
-            $this->parsingCss->save();
4752
-            $this->parsingCss->analyse('tfoot', $param);
4753
-            $this->parsingCss->setPosition();
4754
-            $this->parsingCss->fontSet();
4755
-
4756
-            return true;
4757
-        }
4758
-
4759
-        /**
4760
-         * It is not a real TAG, does not use it !
4761
-         *
4762
-         * @param  array $param
4763
-         * @return boolean
4764
-         */
4765
-        protected function _tag_close_TFOOT_SUB($param)
4766
-        {
4767
-            if ($this->_isForOneLine) return false;
4768
-
4769
-            $this->parsingCss->load();
4770
-            $this->parsingCss->fontSet();
4771
-
4772
-            return true;
4773
-        }
4774
-
4775
-        /**
4776
-         * tag : FORM
4777
-         * mode : OPEN
4778
-         *
4779
-         * @param  array $param
4780
-         * @return boolean
4781
-         */
4782
-        protected function _tag_open_FORM($param)
4783
-        {
4784
-            $this->parsingCss->save();
4785
-            $this->parsingCss->analyse('form', $param);
4786
-            $this->parsingCss->setPosition();
4787
-            $this->parsingCss->fontSet();
4788
-
4789
-            $this->pdf->setFormDefaultProp(
4790
-                array(
4791
-                    'lineWidth'=>1,
4792
-                    'borderStyle'=>'solid',
4793
-                    'fillColor'=>array(220, 220, 255),
4794
-                    'strokeColor'=>array(128, 128, 200)
4795
-                )
4796
-            );
4797
-
4798
-            $this->_isInForm = isset($param['action']) ? $param['action'] : '';
4799
-
4800
-            return true;
4801
-        }
4802
-
4803
-        /**
4804
-         * tag : FORM
4805
-         * mode : CLOSE
4806
-         *
4807
-         * @param  array $param
4808
-         * @return boolean
4809
-         */
4810
-        protected function _tag_close_FORM($param)
4811
-        {
4812
-            $this->_isInForm = false;
4813
-            $this->parsingCss->load();
4814
-            $this->parsingCss->fontSet();
4815
-
4816
-            return true;
4817
-        }
4818
-
4819
-        /**
4820
-         * tag : TABLE
4821
-         * mode : OPEN
4822
-         *
4823
-         * @param  array $param
4824
-         * @return boolean
4825
-         */
4826
-        protected function _tag_open_TABLE($param, $other = 'table')
4827
-        {
4828
-            if ($this->_maxH) {
4829
-                if ($this->_isForOneLine) return false;
4830
-                $this->_tag_open_BR(array());
4831
-            }
4832
-
4833
-            if ($this->_isForOneLine) {
4834
-                $this->_maxX = $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
4835
-                return false;
4836
-            }
4837
-
4838
-            $this->_maxH = 0;
4839
-
4840
-            $alignObject = isset($param['align']) ? strtolower($param['align']) : 'left';
4841
-            if (isset($param['align'])) unset($param['align']);
4842
-            if (!in_array($alignObject, array('left', 'center', 'right'))) $alignObject = 'left';
4843
-
4844
-            $this->parsingCss->save();
4845
-            $this->parsingCss->analyse($other, $param);
4846
-            $this->parsingCss->setPosition();
4847
-            $this->parsingCss->fontSet();
4848
-
4849
-            if ($this->parsingCss->value['margin-auto']) $alignObject = 'center';
4850
-
4851
-            // collapse table ?
4852
-            $collapse = false;
4853
-            if ($other=='table') {
4854
-                $collapse = isset($this->parsingCss->value['border']['collapse']) ? $this->parsingCss->value['border']['collapse'] : false;
4855
-            }
4856
-
4857
-            // if collapse => no borders for the table, only for TD
4858
-            if ($collapse) {
4859
-                $param['style']['border'] = 'none';
4860
-                $param['cellspacing'] = 0;
4861
-                $none = $this->parsingCss->readBorder('none');
4862
-                $this->parsingCss->value['border']['t'] = $none;
4863
-                $this->parsingCss->value['border']['r'] = $none;
4864
-                $this->parsingCss->value['border']['b'] = $none;
4865
-                $this->parsingCss->value['border']['l'] = $none;
4866
-            }
4867
-
4868
-            // if we are in a SUB html => prepare the properties of the table
4869
-            if ($this->_subPart) {
4870
-                if ($this->_debugActif) $this->_DEBUG_add('Table n'.$param['num'], true);
4871
-                HTML2PDF::$_tables[$param['num']] = array();
4872
-                HTML2PDF::$_tables[$param['num']]['border']          = isset($param['border']) ? $this->parsingCss->readBorder($param['border']) : null;
4873
-                HTML2PDF::$_tables[$param['num']]['cellpadding']     = $this->parsingCss->ConvertToMM(isset($param['cellpadding']) ? $param['cellpadding'] : '1px');
4874
-                HTML2PDF::$_tables[$param['num']]['cellspacing']     = $this->parsingCss->ConvertToMM(isset($param['cellspacing']) ? $param['cellspacing'] : '2px');
4875
-                HTML2PDF::$_tables[$param['num']]['cases']           = array();          // properties of each TR/TD
4876
-                HTML2PDF::$_tables[$param['num']]['corr']            = array();          // link between TR/TD and colspan/rowspan
4877
-                HTML2PDF::$_tables[$param['num']]['corr_x']          = 0;                // position in 'cases'
4878
-                HTML2PDF::$_tables[$param['num']]['corr_y']          = 0;                // position in 'cases'
4879
-                HTML2PDF::$_tables[$param['num']]['td_curr']         = 0;                // current column
4880
-                HTML2PDF::$_tables[$param['num']]['tr_curr']         = 0;                // current row
4881
-                HTML2PDF::$_tables[$param['num']]['curr_x']          = $this->pdf->getX();
4882
-                HTML2PDF::$_tables[$param['num']]['curr_y']          = $this->pdf->getY();
4883
-                HTML2PDF::$_tables[$param['num']]['width']           = 0;                // global width
4884
-                HTML2PDF::$_tables[$param['num']]['height']          = 0;                // global height
4885
-                HTML2PDF::$_tables[$param['num']]['align']           = $alignObject;
4886
-                HTML2PDF::$_tables[$param['num']]['marge']           = array();
4887
-                HTML2PDF::$_tables[$param['num']]['marge']['t']      = $this->parsingCss->value['padding']['t']+$this->parsingCss->value['border']['t']['width']+HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5;
4888
-                HTML2PDF::$_tables[$param['num']]['marge']['r']      = $this->parsingCss->value['padding']['r']+$this->parsingCss->value['border']['r']['width']+HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5;
4889
-                HTML2PDF::$_tables[$param['num']]['marge']['b']      = $this->parsingCss->value['padding']['b']+$this->parsingCss->value['border']['b']['width']+HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5;
4890
-                HTML2PDF::$_tables[$param['num']]['marge']['l']      = $this->parsingCss->value['padding']['l']+$this->parsingCss->value['border']['l']['width']+HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5;
4891
-                HTML2PDF::$_tables[$param['num']]['page']            = 0;                // number of pages
4892
-                HTML2PDF::$_tables[$param['num']]['new_page']        = true;             // flag : new page for the current TR
4893
-                HTML2PDF::$_tables[$param['num']]['style_value']     = null;             // CSS style of the table
4894
-                HTML2PDF::$_tables[$param['num']]['thead']           = array();          // properties on the thead
4895
-                HTML2PDF::$_tables[$param['num']]['tfoot']           = array();          // properties on the tfoot
4896
-                HTML2PDF::$_tables[$param['num']]['thead']['tr']     = array();          // list of the TRs in the thead
4897
-                HTML2PDF::$_tables[$param['num']]['tfoot']['tr']     = array();          // list of the TRs in the tfoot
4898
-                HTML2PDF::$_tables[$param['num']]['thead']['height']    = 0;             // thead height
4899
-                HTML2PDF::$_tables[$param['num']]['tfoot']['height']    = 0;             // tfoot height
4900
-                HTML2PDF::$_tables[$param['num']]['thead']['code'] = array();            // HTML content of the thead
4901
-                HTML2PDF::$_tables[$param['num']]['tfoot']['code'] = array();            // HTML content of the tfoot
4902
-                HTML2PDF::$_tables[$param['num']]['cols']        = array();              // properties of the COLs
4903
-
4904
-                $this->_saveMargin($this->pdf->getlMargin(), $this->pdf->gettMargin(), $this->pdf->getrMargin());
4905
-
4906
-                $this->parsingCss->value['width']-= HTML2PDF::$_tables[$param['num']]['marge']['l'] + HTML2PDF::$_tables[$param['num']]['marge']['r'];
4907
-            } else {
4908
-                // we start from the first page and the first page of the table
4909
-                HTML2PDF::$_tables[$param['num']]['page'] = 0;
4910
-                HTML2PDF::$_tables[$param['num']]['td_curr']    = 0;
4911
-                HTML2PDF::$_tables[$param['num']]['tr_curr']    = 0;
4912
-                HTML2PDF::$_tables[$param['num']]['td_x']        = HTML2PDF::$_tables[$param['num']]['marge']['l']+HTML2PDF::$_tables[$param['num']]['curr_x'];
4913
-                HTML2PDF::$_tables[$param['num']]['td_y']        = HTML2PDF::$_tables[$param['num']]['marge']['t']+HTML2PDF::$_tables[$param['num']]['curr_y'];
4914
-
4915
-                // draw the borders/background of the first page/part of the table
4916
-                $this->_drawRectangle(
4917
-                    HTML2PDF::$_tables[$param['num']]['curr_x'],
4918
-                    HTML2PDF::$_tables[$param['num']]['curr_y'],
4919
-                    HTML2PDF::$_tables[$param['num']]['width'],
4920
-                    isset(HTML2PDF::$_tables[$param['num']]['height'][0]) ? HTML2PDF::$_tables[$param['num']]['height'][0] : null,
4921
-                    $this->parsingCss->value['border'],
4922
-                    $this->parsingCss->value['padding'],
4923
-                    0,
4924
-                    $this->parsingCss->value['background']
4925
-                );
4926
-
4927
-                HTML2PDF::$_tables[$param['num']]['style_value'] = $this->parsingCss->value;
4928
-            }
4929
-
4930
-            return true;
4931
-        }
4932
-
4933
-        /**
4934
-         * tag : TABLE
4935
-         * mode : CLOSE
4936
-         *
4937
-         * @param  array $param
4938
-         * @return boolean
4939
-         */
4940
-        protected function _tag_close_TABLE($param)
4941
-        {
4942
-            if ($this->_isForOneLine) return false;
4943
-
4944
-            $this->_maxH = 0;
4945
-
4946
-            // if we are in a sub HTML
4947
-            if ($this->_subPart) {
4948
-                // calculate the size of each case
4949
-                $this->_calculateTableCellSize(HTML2PDF::$_tables[$param['num']]['cases'], HTML2PDF::$_tables[$param['num']]['corr']);
4950
-
4951
-                // calculate the height of the thead and the tfoot
4952
-                $lst = array('thead', 'tfoot');
4953
-                foreach ($lst as $mode) {
4954
-                    HTML2PDF::$_tables[$param['num']][$mode]['height'] = 0;
4955
-                    foreach (HTML2PDF::$_tables[$param['num']][$mode]['tr'] as $tr) {
4956
-                        // hauteur de la ligne tr
4957
-                        $h = 0;
4958
-                        for ($i=0; $i<count(HTML2PDF::$_tables[$param['num']]['cases'][$tr]); $i++)
4959
-                            if (HTML2PDF::$_tables[$param['num']]['cases'][$tr][$i]['rowspan']==1)
4960
-                                $h = max($h, HTML2PDF::$_tables[$param['num']]['cases'][$tr][$i]['h']);
4961
-                        HTML2PDF::$_tables[$param['num']][$mode]['height']+= $h;
4962
-                    }
4963
-                }
4964
-
4965
-                // calculate the width of the table
4966
-                HTML2PDF::$_tables[$param['num']]['width'] = HTML2PDF::$_tables[$param['num']]['marge']['l'] + HTML2PDF::$_tables[$param['num']]['marge']['r'];
4967
-                if (isset(HTML2PDF::$_tables[$param['num']]['cases'][0])) {
4968
-                    foreach (HTML2PDF::$_tables[$param['num']]['cases'][0] as $case) {
4969
-                        HTML2PDF::$_tables[$param['num']]['width']+= $case['w'];
4970
-                    }
4971
-                }
4972
-
4973
-                // X position of the table
4974
-                $old = $this->parsingCss->getOldValues();
4975
-                $parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
4976
-                $x = HTML2PDF::$_tables[$param['num']]['curr_x'];
4977
-                $w = HTML2PDF::$_tables[$param['num']]['width'];
4978
-                if ($parentWidth>$w) {
4979
-                    if (HTML2PDF::$_tables[$param['num']]['align']=='center')
4980
-                        $x = $x + ($parentWidth-$w)*0.5;
4981
-                    else if (HTML2PDF::$_tables[$param['num']]['align']=='right')
4982
-                        $x = $x + $parentWidth-$w;
4983
-
4984
-                    HTML2PDF::$_tables[$param['num']]['curr_x'] = $x;
4985
-                }
4986
-
4987
-                // calculate the height of the table
4988
-                HTML2PDF::$_tables[$param['num']]['height'] = array();
4989
-
4990
-                // minimum of the height because of margins, and of the thead and tfoot height
4991
-                $h0 = HTML2PDF::$_tables[$param['num']]['marge']['t'] + HTML2PDF::$_tables[$param['num']]['marge']['b'];
4992
-                $h0+= HTML2PDF::$_tables[$param['num']]['thead']['height'] + HTML2PDF::$_tables[$param['num']]['tfoot']['height'];
4993
-
4994
-                // max height of the page
4995
-                $max = $this->pdf->getH() - $this->pdf->getbMargin();
4996
-
4997
-                // current position on the page
4998
-                $y = HTML2PDF::$_tables[$param['num']]['curr_y'];
4999
-                $height = $h0;
5000
-
5001
-                // we get the height of each line
5002
-                for ($k=0; $k<count(HTML2PDF::$_tables[$param['num']]['cases']); $k++) {
5003
-
5004
-                    // if it is a TR of the thead or of the tfoot => skip
5005
-                    if (in_array($k, HTML2PDF::$_tables[$param['num']]['thead']['tr'])) continue;
5006
-                    if (in_array($k, HTML2PDF::$_tables[$param['num']]['tfoot']['tr'])) continue;
5007
-
5008
-                    // height of the line
5009
-                    $th = 0;
5010
-                    $h = 0;
5011
-                    for ($i=0; $i<count(HTML2PDF::$_tables[$param['num']]['cases'][$k]); $i++) {
5012
-                        $h = max($h, HTML2PDF::$_tables[$param['num']]['cases'][$k][$i]['h']);
5013
-
5014
-                        if (HTML2PDF::$_tables[$param['num']]['cases'][$k][$i]['rowspan']==1)
5015
-                            $th = max($th, HTML2PDF::$_tables[$param['num']]['cases'][$k][$i]['h']);
5016
-                    }
5017
-
5018
-                    // if the row does not fit on the page => new page
5019
-                    if ($y+$h+$height>$max) {
5020
-                        if ($height==$h0) $height = null;
5021
-                        HTML2PDF::$_tables[$param['num']]['height'][] = $height;
5022
-                        $height = $h0;
5023
-                        $y = $this->_margeTop;
5024
-                    }
5025
-                    $height+= $th;
5026
-                }
5027
-
5028
-                // if ther is a height at the end, add it
5029
-                if ($height!=$h0 || $k==0) HTML2PDF::$_tables[$param['num']]['height'][] = $height;
5030
-            } else {
5031
-                // if we have tfoor, draw it
5032
-                if (count(HTML2PDF::$_tables[$param['num']]['tfoot']['code'])) {
5033
-                    $tmpTR = HTML2PDF::$_tables[$param['num']]['tr_curr'];
5034
-                    $tmpTD = HTML2PDF::$_tables[$param['num']]['td_curr'];
5035
-                    $oldParsePos = $this->_parsePos;
5036
-                    $oldParseCode = $this->parsingHtml->code;
5037
-
5038
-                    HTML2PDF::$_tables[$param['num']]['tr_curr'] = HTML2PDF::$_tables[$param['num']]['tfoot']['tr'][0];
5039
-                    HTML2PDF::$_tables[$param['num']]['td_curr'] = 0;
5040
-                    $this->_parsePos = 0;
5041
-                    $this->parsingHtml->code = HTML2PDF::$_tables[$param['num']]['tfoot']['code'];
5042
-                    $this->_isInTfoot = true;
5043
-                    $this->_makeHTMLcode();
5044
-                    $this->_isInTfoot = false;
5045
-
5046
-                    $this->_parsePos =     $oldParsePos;
5047
-                    $this->parsingHtml->code = $oldParseCode;
5048
-                    HTML2PDF::$_tables[$param['num']]['tr_curr'] = $tmpTR;
5049
-                    HTML2PDF::$_tables[$param['num']]['td_curr'] = $tmpTD;
5050
-                }
5051
-
5052
-                // get the positions of the end of the table
5053
-                $x = HTML2PDF::$_tables[$param['num']]['curr_x'] + HTML2PDF::$_tables[$param['num']]['width'];
5054
-                if (count(HTML2PDF::$_tables[$param['num']]['height'])>1)
5055
-                    $y = $this->_margeTop+HTML2PDF::$_tables[$param['num']]['height'][count(HTML2PDF::$_tables[$param['num']]['height'])-1];
5056
-                else if (count(HTML2PDF::$_tables[$param['num']]['height'])==1)
5057
-                    $y = HTML2PDF::$_tables[$param['num']]['curr_y']+HTML2PDF::$_tables[$param['num']]['height'][count(HTML2PDF::$_tables[$param['num']]['height'])-1];
5058
-                else
5059
-                    $y = HTML2PDF::$_tables[$param['num']]['curr_y'];
5060
-
5061
-                $this->_maxX = max($this->_maxX, $x);
5062
-                $this->_maxY = max($this->_maxY, $y);
5063
-
5064
-                $this->pdf->setXY($this->pdf->getlMargin(), $y);
5065
-
5066
-                $this->_loadMargin();
5067
-
5068
-                if ($this->_debugActif) $this->_DEBUG_add('Table '.$param['num'], false);
5069
-            }
5070
-
5071
-            $this->parsingCss->load();
5072
-            $this->parsingCss->fontSet();
5073
-
5074
-
5075
-            return true;
5076
-        }
5077
-
5078
-        /**
5079
-         * tag : COL
5080
-         * mode : OPEN
5081
-         *
5082
-         * @param  array $param
5083
-         * @return boolean
5084
-         */
5085
-        protected function _tag_open_COL($param)
5086
-        {
5087
-            $span = isset($param['span']) ? $param['span'] : 1;
5088
-            for ($k=0; $k<$span; $k++)
5089
-                HTML2PDF::$_tables[$param['num']]['cols'][] = $param;
5090
-        }
5091
-
5092
-        /**
5093
-         * tag : COL
5094
-         * mode : CLOSE
5095
-         *
5096
-         * @param  array $param
5097
-         * @return boolean
5098
-         */
5099
-        protected function _tag_close_COL($param)
5100
-        {
5101
-            // there is nothing to do here
5102
-
5103
-            return true;
5104
-        }
5105
-
5106
-        /**
5107
-         * tag : TR
5108
-         * mode : OPEN
5109
-         *
5110
-         * @param  array $param
5111
-         * @return boolean
5112
-         */
5113
-        protected function _tag_open_TR($param, $other = 'tr')
5114
-        {
5115
-            if ($this->_isForOneLine) return false;
5116
-
5117
-            $this->_maxH = 0;
5118
-
5119
-            $this->parsingCss->save();
5120
-            $this->parsingCss->analyse($other, $param);
5121
-            $this->parsingCss->setPosition();
5122
-            $this->parsingCss->fontSet();
5123
-
5124
-            // position in the table
5125
-            HTML2PDF::$_tables[$param['num']]['tr_curr']++;
5126
-            HTML2PDF::$_tables[$param['num']]['td_curr']= 0;
5127
-
5128
-            // if we are not in a sub html
5129
-            if (!$this->_subPart) {
5130
-
5131
-                // Y after the row
5132
-                $ty=null;
5133
-                for ($ii=0; $ii<count(HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1]); $ii++) {
5134
-                    $ty = max($ty, HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][$ii]['h']);
5135
-                }
5136
-
5137
-                // height of the tfoot
5138
-                $hfoot = HTML2PDF::$_tables[$param['num']]['tfoot']['height'];
5139
-
5140
-                // if the line does not fit on the page => new page
5141
-                if (!$this->_isInTfoot && HTML2PDF::$_tables[$param['num']]['td_y'] + HTML2PDF::$_tables[$param['num']]['marge']['b'] + $ty +$hfoot> $this->pdf->getH() - $this->pdf->getbMargin()) {
5142
-
5143
-                    // fi ther is a tfoot => draw it
5144
-                    if (count(HTML2PDF::$_tables[$param['num']]['tfoot']['code'])) {
5145
-                        $tmpTR = HTML2PDF::$_tables[$param['num']]['tr_curr'];
5146
-                        $tmpTD = HTML2PDF::$_tables[$param['num']]['td_curr'];
5147
-                        $oldParsePos = $this->_parsePos;
5148
-                        $oldParseCode = $this->parsingHtml->code;
5149
-
5150
-                        HTML2PDF::$_tables[$param['num']]['tr_curr'] = HTML2PDF::$_tables[$param['num']]['tfoot']['tr'][0];
5151
-                        HTML2PDF::$_tables[$param['num']]['td_curr'] = 0;
5152
-                        $this->_parsePos = 0;
5153
-                        $this->parsingHtml->code = HTML2PDF::$_tables[$param['num']]['tfoot']['code'];
5154
-                        $this->_isInTfoot = true;
5155
-                        $this->_makeHTMLcode();
5156
-                        $this->_isInTfoot = false;
5157
-
5158
-                        $this->_parsePos =     $oldParsePos;
5159
-                        $this->parsingHtml->code = $oldParseCode;
5160
-                        HTML2PDF::$_tables[$param['num']]['tr_curr'] = $tmpTR;
5161
-                        HTML2PDF::$_tables[$param['num']]['td_curr'] = $tmpTD;
5162
-                    }
5163
-
5164
-                    // new page
5165
-                    HTML2PDF::$_tables[$param['num']]['new_page'] = true;
5166
-                    $this->_setNewPage();
5167
-
5168
-                    // new position
5169
-                    HTML2PDF::$_tables[$param['num']]['page']++;
5170
-                    HTML2PDF::$_tables[$param['num']]['curr_y'] = $this->pdf->getY();
5171
-                    HTML2PDF::$_tables[$param['num']]['td_y'] = HTML2PDF::$_tables[$param['num']]['curr_y']+HTML2PDF::$_tables[$param['num']]['marge']['t'];
5172
-
5173
-                    // if we have the height of the tbale on the page => draw borders and background
5174
-                    if (isset(HTML2PDF::$_tables[$param['num']]['height'][HTML2PDF::$_tables[$param['num']]['page']])) {
5175
-                        $old = $this->parsingCss->value;
5176
-                        $this->parsingCss->value = HTML2PDF::$_tables[$param['num']]['style_value'];
5177
-
5178
-                        $this->_drawRectangle(
5179
-                            HTML2PDF::$_tables[$param['num']]['curr_x'],
5180
-                            HTML2PDF::$_tables[$param['num']]['curr_y'],
5181
-                            HTML2PDF::$_tables[$param['num']]['width'],
5182
-                            HTML2PDF::$_tables[$param['num']]['height'][HTML2PDF::$_tables[$param['num']]['page']],
5183
-                            $this->parsingCss->value['border'],
5184
-                            $this->parsingCss->value['padding'],
5185
-                            HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5,
5186
-                            $this->parsingCss->value['background']
5187
-                        );
5188
-
5189
-                        $this->parsingCss->value = $old;
5190
-                    }
5191
-                }
5192
-
5193
-                // if we are in a new page, and if we have a thead => draw it
5194
-                if (HTML2PDF::$_tables[$param['num']]['new_page'] && count(HTML2PDF::$_tables[$param['num']]['thead']['code'])) {
5195
-                    HTML2PDF::$_tables[$param['num']]['new_page'] = false;
5196
-                    $tmpTR = HTML2PDF::$_tables[$param['num']]['tr_curr'];
5197
-                    $tmpTD = HTML2PDF::$_tables[$param['num']]['td_curr'];
5198
-                    $oldParsePos = $this->_parsePos;
5199
-                    $oldParseCode = $this->parsingHtml->code;
5200
-
5201
-                    HTML2PDF::$_tables[$param['num']]['tr_curr'] = HTML2PDF::$_tables[$param['num']]['thead']['tr'][0];
5202
-                    HTML2PDF::$_tables[$param['num']]['td_curr'] = 0;
5203
-                    $this->_parsePos = 0;
5204
-                    $this->parsingHtml->code = HTML2PDF::$_tables[$param['num']]['thead']['code'];
5205
-                    $this->_isInThead = true;
5206
-                    $this->_makeHTMLcode();
5207
-                    $this->_isInThead = false;
5208
-
5209
-                    $this->_parsePos =     $oldParsePos;
5210
-                    $this->parsingHtml->code = $oldParseCode;
5211
-                    HTML2PDF::$_tables[$param['num']]['tr_curr'] = $tmpTR;
5212
-                    HTML2PDF::$_tables[$param['num']]['td_curr'] = $tmpTD;
5213
-                    HTML2PDF::$_tables[$param['num']]['new_page'] = true;
5214
-                }
5215
-            // else (in a sub HTML)
5216
-            } else {
5217
-                // prepare it
5218
-                HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1] = array();
5219
-                if (!isset(HTML2PDF::$_tables[$param['num']]['corr'][HTML2PDF::$_tables[$param['num']]['corr_y']]))
5220
-                    HTML2PDF::$_tables[$param['num']]['corr'][HTML2PDF::$_tables[$param['num']]['corr_y']] = array();
5221
-
5222
-                HTML2PDF::$_tables[$param['num']]['corr_x']=0;
5223
-                while(isset(HTML2PDF::$_tables[$param['num']]['corr'][HTML2PDF::$_tables[$param['num']]['corr_y']][HTML2PDF::$_tables[$param['num']]['corr_x']]))
5224
-                    HTML2PDF::$_tables[$param['num']]['corr_x']++;
5225
-            }
5226
-
5227
-            return true;
5228
-        }
5229
-
5230
-        /**
5231
-         * tag : TR
5232
-         * mode : CLOSE
5233
-         *
5234
-         * @param  array $param
5235
-         * @return boolean
5236
-         */
5237
-        protected function _tag_close_TR($param)
5238
-        {
5239
-            if ($this->_isForOneLine) return false;
5240
-
5241
-            $this->_maxH = 0;
5242
-
5243
-            $this->parsingCss->load();
5244
-            $this->parsingCss->fontSet();
5245
-
5246
-            // if we are not in a sub HTML
5247
-            if (!$this->_subPart) {
5248
-
5249
-                // Y of the current line
5250
-                $ty=null;
5251
-                for ($ii=0; $ii<count(HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1]); $ii++) {
5252
-                    if (HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][$ii]['rowspan']==1) {
5253
-                        $ty = HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][$ii]['h'];
5254
-                    }
5255
-                }
5256
-
5257
-                // new position
5258
-                HTML2PDF::$_tables[$param['num']]['td_x'] = HTML2PDF::$_tables[$param['num']]['curr_x']+HTML2PDF::$_tables[$param['num']]['marge']['l'];
5259
-                HTML2PDF::$_tables[$param['num']]['td_y']+= $ty;
5260
-                HTML2PDF::$_tables[$param['num']]['new_page'] = false;
5261
-            } else {
5262
-                HTML2PDF::$_tables[$param['num']]['corr_y']++;
5263
-            }
5264
-
5265
-            return true;
5266
-        }
5267
-
5268
-        /**
5269
-         * tag : TD
5270
-         * mode : OPEN
5271
-         *
5272
-         * @param  array $param
5273
-         * @return boolean
5274
-         */
5275
-        protected function _tag_open_TD($param, $other = 'td')
5276
-        {
5277
-            if ($this->_isForOneLine) return false;
5278
-
5279
-            $this->_maxH = 0;
5280
-
5281
-            $param['cellpadding'] = HTML2PDF::$_tables[$param['num']]['cellpadding'].'mm';
5282
-            $param['cellspacing'] = HTML2PDF::$_tables[$param['num']]['cellspacing'].'mm';
5283
-
5284
-            // specific style for LI
5285
-            if ($other=='li') {
5286
-                $specialLi = true;
5287
-            } else {
5288
-                $specialLi = false;
5289
-                if ($other=='li_sub') {
5290
-                    $param['style']['border'] = 'none';
5291
-                    $param['style']['background-color']    = 'transparent';
5292
-                    $param['style']['background-image']    = 'none';
5293
-                    $param['style']['background-position'] = '';
5294
-                    $param['style']['background-repeat']   = '';
5295
-                    $other = 'li';
5296
-                }
5297
-            }
5298
-
5299
-            // get the properties of the TD
5300
-            $x = HTML2PDF::$_tables[$param['num']]['td_curr'];
5301
-            $y = HTML2PDF::$_tables[$param['num']]['tr_curr']-1;
5302
-            $colspan = isset($param['colspan']) ? $param['colspan'] : 1;
5303
-            $rowspan = isset($param['rowspan']) ? $param['rowspan'] : 1;
5304
-
5305
-            // flag for collapse table
5306
-            $collapse = false;
5307
-
5308
-            // specific traitment for TD and TH
5309
-            if (in_array($other, array('td', 'th'))) {
5310
-                // id of the column
5311
-                $numCol = isset(HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['Xr']) ? HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['Xr'] : HTML2PDF::$_tables[$param['num']]['corr_x'];
5312
-
5313
-                // we get the properties of the COL tag, if exist
5314
-                if (isset(HTML2PDF::$_tables[$param['num']]['cols'][$numCol])) {
5315
-
5316
-                    $colParam = HTML2PDF::$_tables[$param['num']]['cols'][$numCol];
5317
-
5318
-                    // for colspans => we get all the neede widths
5319
-                    $colParam['style']['width'] = array();
5320
-                    for ($k=0; $k<$colspan; $k++) {
5321
-                        if (isset(HTML2PDF::$_tables[$param['num']]['cols'][$numCol+$k]['style']['width'])) {
5322
-                            $colParam['style']['width'][] = HTML2PDF::$_tables[$param['num']]['cols'][$numCol+$k]['style']['width'];
5323
-                        }
5324
-                    }
5325
-
5326
-                    // calculate the total width of the column
5327
-                    $total = '';
5328
-                    $last = $this->parsingCss->getLastWidth();
5329
-                    if (count($colParam['style']['width'])) {
5330
-                        $total = $colParam['style']['width'][0]; unset($colParam['style']['width'][0]);
5331
-                        foreach ($colParam['style']['width'] as $width) {
5332
-                            if (substr($total, -1)=='%' && substr($width, -1)=='%')
5333
-                                $total = (str_replace('%', '', $total)+str_replace('%', '', $width)).'%';
5334
-                            else
5335
-                                $total = ($this->parsingCss->ConvertToMM($total, $last) + $this->parsingCss->ConvertToMM($width, $last)).'mm';
5336
-                        }
5337
-                    }
5338
-
5339
-                    // get the final width
5340
-                    if ($total) {
5341
-                        $colParam['style']['width'] = $total;
5342
-                    } else {
5343
-                        unset($colParam['style']['width']);
5344
-                    }
5345
-
5346
-
5347
-                    // merge the styles of the COL and the TD
5348
-                    $param['style'] = array_merge($colParam['style'], $param['style']);
5349
-
5350
-                    // merge the class of the COL and the TD
5351
-                    if (isset($colParam['class'])) {
5352
-                        $param['class'] = $colParam['class'].(isset($param['class']) ? ' '.$param['class'] : '');
5353
-                    }
5354
-                }
5355
-
5356
-                $collapse = isset($this->parsingCss->value['border']['collapse']) ? $this->parsingCss->value['border']['collapse'] : false;
5357
-            }
5358
-
5359
-            $this->parsingCss->save();
5360
-
5361
-            // legacy for TD and TH
5362
-            $legacy = null;
5363
-            if (in_array($other, array('td', 'th'))) {
5364
-                $legacy = array();
5365
-
5366
-                $old = $this->parsingCss->getLastValue('background');
5367
-                if ($old && ($old['color'] || $old['image']))
5368
-                    $legacy['background'] = $old;
5369
-
5370
-                if (HTML2PDF::$_tables[$param['num']]['border']) {
5371
-                    $legacy['border'] = array();
5372
-                    $legacy['border']['l'] = HTML2PDF::$_tables[$param['num']]['border'];
5373
-                    $legacy['border']['t'] = HTML2PDF::$_tables[$param['num']]['border'];
5374
-                    $legacy['border']['r'] = HTML2PDF::$_tables[$param['num']]['border'];
5375
-                    $legacy['border']['b'] = HTML2PDF::$_tables[$param['num']]['border'];
5376
-                }
5377
-            }
5378
-            $return = $this->parsingCss->analyse($other, $param, $legacy);
5379
-
5380
-            if ($specialLi) {
5381
-                $this->parsingCss->value['width']-= $this->parsingCss->ConvertToMM($this->_listeGetWidth());
5382
-                $this->parsingCss->value['width']-= $this->parsingCss->ConvertToMM($this->_listeGetPadding());
5383
-            }
5384
-            $this->parsingCss->setPosition();
5385
-            $this->parsingCss->fontSet();
5386
-
5387
-            // if tale collapse => modify the borders
5388
-            if ($collapse) {
5389
-                if (!$this->_subPart) {
5390
-                    if (
5391
-                        (HTML2PDF::$_tables[$param['num']]['tr_curr']>1 && !HTML2PDF::$_tables[$param['num']]['new_page']) ||
5392
-                        (!$this->_isInThead && count(HTML2PDF::$_tables[$param['num']]['thead']['code']))
5393
-                    ) {
5394
-                        $this->parsingCss->value['border']['t'] = $this->parsingCss->readBorder('none');
5395
-                    }
5396
-                }
5397
-
5398
-                if (HTML2PDF::$_tables[$param['num']]['td_curr']>0) {
5399
-                    if (!$return) $this->parsingCss->value['width']+= $this->parsingCss->value['border']['l']['width'];
5400
-                    $this->parsingCss->value['border']['l'] = $this->parsingCss->readBorder('none');
5401
-                }
5402
-            }
5403
-
5404
-            // margins of the table
5405
-            $marge = array();
5406
-            $marge['t'] = $this->parsingCss->value['padding']['t']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['t']['width'];
5407
-            $marge['r'] = $this->parsingCss->value['padding']['r']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['r']['width'];
5408
-            $marge['b'] = $this->parsingCss->value['padding']['b']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['b']['width'];
5409
-            $marge['l'] = $this->parsingCss->value['padding']['l']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['l']['width'];
5410
-
5411
-            // if we are in a sub HTML
5412
-            if ($this->_subPart) {
5413
-                // new position in the table
5414
-                HTML2PDF::$_tables[$param['num']]['td_curr']++;
5415
-                HTML2PDF::$_tables[$param['num']]['cases'][$y][$x] = array();
5416
-                HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['w'] = 0;
5417
-                HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['h'] = 0;
5418
-                HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['dw'] = 0;
5419
-                HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['colspan'] = $colspan;
5420
-                HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['rowspan'] = $rowspan;
5421
-                HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['Xr'] = HTML2PDF::$_tables[$param['num']]['corr_x'];
5422
-                HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['Yr'] = HTML2PDF::$_tables[$param['num']]['corr_y'];
5423
-
5424
-                // prepare the mapping for rowspan and colspan
5425
-                for ($j=0; $j<$rowspan; $j++) {
5426
-                    for ($i=0; $i<$colspan; $i++) {
5427
-                        HTML2PDF::$_tables[$param['num']]['corr']
5428
-                            [HTML2PDF::$_tables[$param['num']]['corr_y']+$j]
5429
-                            [HTML2PDF::$_tables[$param['num']]['corr_x']+$i] = ($i+$j>0) ? '' : array($x,$y,$colspan,$rowspan);
5430
-                    }
5431
-                }
5432
-                HTML2PDF::$_tables[$param['num']]['corr_x']+= $colspan;
5433
-                while (isset(HTML2PDF::$_tables[$param['num']]['corr'][HTML2PDF::$_tables[$param['num']]['corr_y']][HTML2PDF::$_tables[$param['num']]['corr_x']])) {
5434
-                    HTML2PDF::$_tables[$param['num']]['corr_x']++;
5435
-                }
5436
-
5437
-                // extract the content of the TD, and calculate his size
5438
-                $level = $this->parsingHtml->getLevel($this->_tempPos);
5439
-                $this->_createSubHTML($this->_subHtml);
5440
-                $this->_subHtml->parsingHtml->code = $level;
5441
-                $this->_subHtml->_makeHTMLcode();
5442
-                $this->_tempPos+= count($level);
5443
-            } else {
5444
-                // new position in the table
5445
-                HTML2PDF::$_tables[$param['num']]['td_curr']++;
5446
-                HTML2PDF::$_tables[$param['num']]['td_x']+= HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['dw'];
5447
-
5448
-                // borders and background of the TD
5449
-                $this->_drawRectangle(
5450
-                    HTML2PDF::$_tables[$param['num']]['td_x'],
5451
-                    HTML2PDF::$_tables[$param['num']]['td_y'],
5452
-                    HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['w'],
5453
-                    HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['h'],
5454
-                    $this->parsingCss->value['border'],
5455
-                    $this->parsingCss->value['padding'],
5456
-                    HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5,
5457
-                    $this->parsingCss->value['background']
5458
-                );
5459
-
5460
-                $this->parsingCss->value['width'] = HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['w'] - $marge['l'] - $marge['r'];
5461
-
5462
-                // marges = size of the TD
5463
-                $mL = HTML2PDF::$_tables[$param['num']]['td_x']+$marge['l'];
5464
-                $mR = $this->pdf->getW() - $mL - $this->parsingCss->value['width'];
5465
-                $this->_saveMargin($mL, 0, $mR);
5466
-
5467
-                // position of the content, from vertical-align
5468
-                $hCorr = HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['h'];
5469
-                $hReel = HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['real_h'];
5470
-                switch($this->parsingCss->value['vertical-align'])
5471
-                {
5472
-                    case 'bottom':
5473
-                        $yCorr = $hCorr-$hReel;
5474
-                        break;
5475
-
5476
-                    case 'middle':
5477
-                        $yCorr = ($hCorr-$hReel)*0.5;
5478
-                        break;
5479
-
5480
-                    case 'top':
5481
-                    default:
5482
-                        $yCorr = 0;
5483
-                        break;
5484
-                }
5485
-
5486
-                //  position of the content
5487
-                $x = HTML2PDF::$_tables[$param['num']]['td_x']+$marge['l'];
5488
-                $y = HTML2PDF::$_tables[$param['num']]['td_y']+$marge['t']+$yCorr;
5489
-                $this->pdf->setXY($x, $y);
5490
-                $this->_setNewPositionForNewLine();
5491
-            }
5492
-
5493
-            return true;
5494
-        }
5495
-
5496
-        /**
5497
-         * tag : TD
5498
-         * mode : CLOSE
5499
-         *
5500
-         * @param    array $param
5501
-         * @return boolean
5502
-         */
5503
-        protected function _tag_close_TD($param)
5504
-        {
5505
-            if ($this->_isForOneLine) return false;
5506
-
5507
-            $this->_maxH = 0;
5508
-
5509
-            // get the margins
5510
-            $marge = array();
5511
-            $marge['t'] = $this->parsingCss->value['padding']['t']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['t']['width'];
5512
-            $marge['r'] = $this->parsingCss->value['padding']['r']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['r']['width'];
5513
-            $marge['b'] = $this->parsingCss->value['padding']['b']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['b']['width'];
5514
-            $marge['l'] = $this->parsingCss->value['padding']['l']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['l']['width'];
5515
-            $marge['t']+= 0.001;
5516
-            $marge['r']+= 0.001;
5517
-            $marge['b']+= 0.001;
5518
-            $marge['l']+= 0.001;
5519
-
5520
-            // if we are in a sub HTML
5521
-            if ($this->_subPart) {
5522
-
5523
-                // it msut take only one page
5524
-                if ($this->_testTdInOnepage && $this->_subHtml->pdf->getPage()>1) {
5525
-                    throw new HTML2PDF_exception(7);
5526
-                }
5527
-
5528
-                // size of the content of the TD
5529
-                $w0 = $this->_subHtml->_maxX + $marge['l'] + $marge['r'];
5530
-                $h0 = $this->_subHtml->_maxY + $marge['t'] + $marge['b'];
5531
-
5532
-                // size from the CSS style
5533
-                $w2 = $this->parsingCss->value['width'] + $marge['l'] + $marge['r'];
5534
-                $h2 = $this->parsingCss->value['height'] + $marge['t'] + $marge['b'];
5535
-
5536
-                // final size of the TD
5537
-                HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][HTML2PDF::$_tables[$param['num']]['td_curr']-1]['w'] = max(array($w0, $w2));
5538
-                HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][HTML2PDF::$_tables[$param['num']]['td_curr']-1]['h'] = max(array($h0, $h2));
5539
-
5540
-                // real position of the content
5541
-                HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][HTML2PDF::$_tables[$param['num']]['td_curr']-1]['real_w'] = $w0;
5542
-                HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][HTML2PDF::$_tables[$param['num']]['td_curr']-1]['real_h'] = $h0;
5543
-
5544
-                // destroy the sub HTML
5545
-                $this->_destroySubHTML($this->_subHtml);
5546
-            } else {
5547
-                $this->_loadMargin();
5548
-
5549
-                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'];
5550
-            }
5551
-
5552
-            $this->parsingCss->load();
5553
-            $this->parsingCss->fontSet();
5554
-
5555
-            return true;
5556
-        }
5557
-
5558
-
5559
-        /**
5560
-         * tag : TH
5561
-         * mode : OPEN
5562
-         *
5563
-         * @param  array $param
5564
-         * @return boolean
5565
-         */
5566
-        protected function _tag_open_TH($param)
5567
-        {
5568
-            if ($this->_isForOneLine) return false;
5569
-
5570
-            $this->parsingCss->save();
5571
-            $this->parsingCss->value['font-bold'] = true;
5572
-
5573
-            $this->_tag_open_TD($param, 'th');
5574
-
5575
-            return true;
5576
-        }
5577
-
5578
-        /**
5579
-         * tag : TH
5580
-         * mode : CLOSE
5581
-         *
5582
-         * @param  array $param
5583
-         * @return boolean
5584
-         */
5585
-        protected function _tag_close_TH($param)
5586
-        {
5587
-            if ($this->_isForOneLine) return false;
5588
-
5589
-            $this->_tag_close_TD($param);
5590
-
5591
-            $this->parsingCss->load();
5592
-
5593
-            return true;
5594
-        }
5595
-
5596
-        /**
5597
-         * tag : IMG
5598
-         * mode : OPEN
5599
-         *
5600
-         * @param  array $param
5601
-         * @return boolean
5602
-         */
5603
-        protected function _tag_open_IMG($param)
5604
-        {
5605
-            $src    = str_replace('&amp;', '&', $param['src']);
5606
-
5607
-            $this->parsingCss->save();
5608
-            $this->parsingCss->value['width']    = 0;
5609
-            $this->parsingCss->value['height']    = 0;
5610
-            $this->parsingCss->value['border']    = array('type' => 'none', 'width' => 0, 'color' => array(0, 0, 0));
5611
-            $this->parsingCss->value['background'] = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
5612
-            $this->parsingCss->analyse('img', $param);
5613
-            $this->parsingCss->setPosition();
5614
-            $this->parsingCss->fontSet();
5615
-
5616
-            $res = $this->_drawImage($src, isset($param['sub_li']));
5617
-            if (!$res) return $res;
5618
-
5619
-            $this->parsingCss->load();
5620
-            $this->parsingCss->fontSet();
5621
-            $this->_maxE++;
5622
-
5623
-            return true;
5624
-        }
5625
-
5626
-        /**
5627
-         * tag : SELECT
5628
-         * mode : OPEN
5629
-         *
5630
-         * @param  array $param
5631
-         * @return boolean
5632
-         */
5633
-        protected function _tag_open_SELECT($param)
5634
-        {
5635
-            if (!isset($param['name'])) {
5636
-                $param['name'] = 'champs_pdf_'.(count($this->_lstField)+1);
5637
-            }
5638
-
5639
-            $param['name'] = strtolower($param['name']);
5640
-
5641
-            if (isset($this->_lstField[$param['name']])) {
5642
-                $this->_lstField[$param['name']]++;
5643
-            } else {
5644
-                $this->_lstField[$param['name']] = 1;
5645
-            }
5646
-
5647
-            $this->parsingCss->save();
5648
-            $this->parsingCss->analyse('select', $param);
5649
-            $this->parsingCss->setPosition();
5650
-            $this->parsingCss->fontSet();
5651
-
5652
-            $this->_lstSelect = array();
5653
-            $this->_lstSelect['name']    = $param['name'];
5654
-            $this->_lstSelect['multi']    = isset($param['multiple']) ? true : false;
5655
-            $this->_lstSelect['size']    = isset($param['size']) ? $param['size'] : 1;
5656
-            $this->_lstSelect['options']    = array();
5657
-
5658
-            if ($this->_lstSelect['multi'] && $this->_lstSelect['size']<3) $this->_lstSelect['size'] = 3;
5659
-
5660
-            return true;
5661
-        }
5662
-
5663
-        /**
5664
-         * tag : OPTION
5665
-         * mode : OPEN
5666
-         *
5667
-         * @param    array $param
5668
-         * @return boolean
5669
-         */
5670
-        protected function _tag_open_OPTION($param)
5671
-        {
5672
-            // get the content of the option : it is the text of the option
5673
-            $level = $this->parsingHtml->getLevel($this->_parsePos);
5674
-            $this->_parsePos+= count($level);
5675
-            $value = isset($param['value']) ? $param['value'] : 'aut_tag_open_opt_'.(count($this->_lstSelect)+1);
5676
-
5677
-            $this->_lstSelect['options'][$value] = isset($level[0]['param']['txt']) ? $level[0]['param']['txt'] : '';
5678
-
5679
-            return true;
5680
-        }
5681
-
5682
-        /**
5683
-         * tag : OPTION
5684
-         * mode : CLOSE
5685
-         *
5686
-         * @param    array $param
5687
-         * @return boolean
5688
-         */
5689
-        protected function _tag_close_OPTION($param)
5690
-        {
5691
-            // nothing to do here
5692
-
5693
-            return true;
5694
-        }
5695
-
5696
-        /**
5697
-         * tag : SELECT
5698
-         * mode : CLOSE
5699
-         *
5700
-         * @param  array $param
5701
-         * @return boolean
5702
-         */
5703
-        protected function _tag_close_SELECT()
5704
-        {
5705
-            // position of the select
5706
-            $x = $this->pdf->getX();
5707
-            $y = $this->pdf->getY();
5708
-            $f = 1.08*$this->parsingCss->value['font-size'];
5709
-
5710
-            // width
5711
-            $w = $this->parsingCss->value['width']; if (!$w) $w = 50;
5712
-
5713
-            // height (automatic)
5714
-            $h = ($f*1.07*$this->_lstSelect['size'] + 1);
5715
-
5716
-            $prop = $this->parsingCss->getFormStyle();
5717
-
5718
-            // multy select
5719
-            if ($this->_lstSelect['multi']) {
5720
-                $prop['multipleSelection'] = 'true';
5721
-            }
5722
-
5723
-
5724
-            // single or multi select
5725
-            if ($this->_lstSelect['size']>1) {
5726
-                $this->pdf->ListBox($this->_lstSelect['name'], $w, $h, $this->_lstSelect['options'], $prop);
5727
-            } else {
5728
-                $this->pdf->ComboBox($this->_lstSelect['name'], $w, $h, $this->_lstSelect['options'], $prop);
5729
-            }
5730
-
5731
-            $this->_maxX = max($this->_maxX, $x+$w);
5732
-            $this->_maxY = max($this->_maxY, $y+$h);
5733
-            $this->_maxH = max($this->_maxH, $h);
5734
-            $this->_maxE++;
5735
-            $this->pdf->setX($x+$w);
5736
-
5737
-            $this->parsingCss->load();
5738
-            $this->parsingCss->fontSet();
5739
-
5740
-            $this->_lstSelect = array();
5741
-
5742
-            return true;
5743
-        }
5744
-
5745
-        /**
5746
-         * tag : TEXTAREA
5747
-         * mode : OPEN
5748
-         *
5749
-         * @param    array $param
5750
-         * @return boolean
5751
-         */
5752
-        protected function _tag_open_TEXTAREA($param)
5753
-        {
5754
-            if (!isset($param['name'])) {
5755
-                $param['name'] = 'champs_pdf_'.(count($this->_lstField)+1);
5756
-            }
5757
-
5758
-            $param['name'] = strtolower($param['name']);
5759
-
5760
-            if (isset($this->_lstField[$param['name']])) {
5761
-                $this->_lstField[$param['name']]++;
5762
-            } else {
5763
-                $this->_lstField[$param['name']] = 1;
5764
-            }
5765
-
5766
-            $this->parsingCss->save();
5767
-            $this->parsingCss->analyse('textarea', $param);
5768
-            $this->parsingCss->setPosition();
5769
-            $this->parsingCss->fontSet();
5770
-
5771
-            $x = $this->pdf->getX();
5772
-            $y = $this->pdf->getY();
5773
-            $fx = 0.65*$this->parsingCss->value['font-size'];
5774
-            $fy = 1.08*$this->parsingCss->value['font-size'];
5775
-
5776
-            // extract the content the textarea : value
5777
-            $level = $this->parsingHtml->getLevel($this->_parsePos);
5778
-            $this->_parsePos+= count($level);
5779
-
5780
-            // automatic size, from cols and rows properties
5781
-            $w = $fx*(isset($param['cols']) ? $param['cols'] : 22)+1;
5782
-            $h = $fy*1.07*(isset($param['rows']) ? $param['rows'] : 3)+3;
5783
-
5784
-            $prop = $this->parsingCss->getFormStyle();
5785
-
5786
-            $prop['multiline'] = true;
5787
-            $prop['value'] = isset($level[0]['param']['txt']) ? $level[0]['param']['txt'] : '';
5788
-
5789
-            $this->pdf->TextField($param['name'], $w, $h, $prop, array(), $x, $y);
5790
-
5791
-            $this->_maxX = max($this->_maxX, $x+$w);
5792
-            $this->_maxY = max($this->_maxY, $y+$h);
5793
-            $this->_maxH = max($this->_maxH, $h);
5794
-            $this->_maxE++;
5795
-            $this->pdf->setX($x+$w);
5796
-
5797
-            return true;
5798
-        }
5799
-
5800
-        /**
5801
-         * tag : TEXTAREA
5802
-         * mode : CLOSE
5803
-         *
5804
-         * @param  array $param
5805
-         * @return boolean
5806
-         */
5807
-        protected function _tag_close_TEXTAREA()
5808
-        {
5809
-            $this->parsingCss->load();
5810
-            $this->parsingCss->fontSet();
5811
-
5812
-            return true;
5813
-        }
5814
-
5815
-        /**
5816
-         * tag : INPUT
5817
-         * mode : OPEN
5818
-         *
5819
-         * @param  array $param
5820
-         * @return boolean
5821
-         */
5822
-        protected function _tag_open_INPUT($param)
5823
-        {
5824
-            if (!isset($param['name']))  $param['name']  = 'champs_pdf_'.(count($this->_lstField)+1);
5825
-            if (!isset($param['value'])) $param['value'] = '';
5826
-            if (!isset($param['type']))  $param['type']  = 'text';
5827
-
5828
-            $param['name'] = strtolower($param['name']);
5829
-            $param['type'] = strtolower($param['type']);
5830
-
5831
-            // the type must be valid
5832
-            if (!in_array($param['type'], array('text', 'checkbox', 'radio', 'hidden', 'submit', 'reset', 'button'))) {
5833
-                $param['type'] = 'text';
5834
-            }
5835
-
5836
-            if (isset($this->_lstField[$param['name']])) {
5837
-                $this->_lstField[$param['name']]++;
5838
-            } else {
5839
-                $this->_lstField[$param['name']] = 1;
5840
-            }
5841
-
5842
-            $this->parsingCss->save();
5843
-            $this->parsingCss->analyse('input', $param);
5844
-            $this->parsingCss->setPosition();
5845
-            $this->parsingCss->fontSet();
5846
-
5847
-            $name = $param['name'];
5848
-
5849
-            $x = $this->pdf->getX();
5850
-            $y = $this->pdf->getY();
5851
-            $f = 1.08*$this->parsingCss->value['font-size'];
5852
-
5853
-            $prop = $this->parsingCss->getFormStyle();
5854
-
5855
-            switch($param['type'])
5856
-            {
5857
-                case 'checkbox':
5858
-                    $w = 3;
5859
-                    $h = $w;
5860
-                    if ($h<$f) $y+= ($f-$h)*0.5;
5861
-                    $checked = (isset($param['checked']) && $param['checked']=='checked');
5862
-                    $this->pdf->CheckBox($name, $w, $checked, $prop, array(), ($param['value'] ? $param['value'] : 'Yes'), $x, $y);
5863
-                    break;
5864
-
5865
-                case 'radio':
5866
-                    $w = 3;
5867
-                    $h = $w;
5868
-                    if ($h<$f) $y+= ($f-$h)*0.5;
5869
-                    $checked = (isset($param['checked']) && $param['checked']=='checked');
5870
-                    $this->pdf->RadioButton($name, $w, $prop, array(), ($param['value'] ? $param['value'] : 'On'), $checked, $x, $y);
5871
-                    break;
5872
-
5873
-                case 'hidden':
5874
-                    $w = 0;
5875
-                    $h = 0;
5876
-                    $prop['value'] = $param['value'];
5877
-                    $this->pdf->TextField($name, $w, $h, $prop, array(), $x, $y);
5878
-                    break;
5879
-
5880
-                case 'text':
5881
-                    $w = $this->parsingCss->value['width']; if (!$w) $w = 40;
5882
-                    $h = $f*1.3;
5883
-                    $prop['value'] = $param['value'];
5884
-                    $this->pdf->TextField($name, $w, $h, $prop, array(), $x, $y);
5885
-                    break;
5886
-
5887
-                case 'submit':
5888
-                    $w = $this->parsingCss->value['width'];    if (!$w) $w = 40;
5889
-                    $h = $this->parsingCss->value['height'];    if (!$h) $h = $f*1.3;
5890
-                    $action = array('S'=>'SubmitForm', 'F'=>$this->_isInForm, 'Flags'=>array('ExportFormat'));
5891
-                    $this->pdf->Button($name, $w, $h, $param['value'], $action, $prop, array(), $x, $y);
5892
-                    break;
5893
-
5894
-                case 'reset':
5895
-                    $w = $this->parsingCss->value['width'];    if (!$w) $w = 40;
5896
-                    $h = $this->parsingCss->value['height'];    if (!$h) $h = $f*1.3;
5897
-                    $action = array('S'=>'ResetForm');
5898
-                    $this->pdf->Button($name, $w, $h, $param['value'], $action, $prop, array(), $x, $y);
5899
-                    break;
5900
-
5901
-                case 'button':
5902
-                    $w = $this->parsingCss->value['width'];    if (!$w) $w = 40;
5903
-                    $h = $this->parsingCss->value['height'];    if (!$h) $h = $f*1.3;
5904
-                    $action = isset($param['onclick']) ? $param['onclick'] : '';
5905
-                    $this->pdf->Button($name, $w, $h, $param['value'], $action, $prop, array(), $x, $y);
5906
-                    break;
5907
-
5908
-                default:
5909
-                    $w = 0;
5910
-                    $h = 0;
5911
-                    break;
5912
-            }
5913
-
5914
-            $this->_maxX = max($this->_maxX, $x+$w);
5915
-            $this->_maxY = max($this->_maxY, $y+$h);
5916
-            $this->_maxH = max($this->_maxH, $h);
5917
-            $this->_maxE++;
5918
-            $this->pdf->setX($x+$w);
5919
-
5920
-            $this->parsingCss->load();
5921
-            $this->parsingCss->fontSet();
5922
-
5923
-            return true;
5924
-        }
5925
-
5926
-        /**
5927
-         * tag : DRAW
5928
-         * mode : OPEN
5929
-         *
5930
-         * @param  array $param
5931
-         * @return boolean
5932
-         */
5933
-        protected function _tag_open_DRAW($param)
5934
-        {
5935
-            if ($this->_isForOneLine) return false;
5936
-            if ($this->_debugActif) $this->_DEBUG_add('DRAW', true);
5937
-
5938
-            $this->parsingCss->save();
5939
-            $this->parsingCss->analyse('draw', $param);
5940
-            $this->parsingCss->fontSet();
5941
-
5942
-            $alignObject = null;
5943
-            if ($this->parsingCss->value['margin-auto']) $alignObject = 'center';
5944
-
5945
-            $overW = $this->parsingCss->value['width'];
5946
-            $overH = $this->parsingCss->value['height'];
5947
-            $this->parsingCss->value['old_maxX'] = $this->_maxX;
5948
-            $this->parsingCss->value['old_maxY'] = $this->_maxY;
5949
-            $this->parsingCss->value['old_maxH'] = $this->_maxH;
5950
-
5951
-            $w = $this->parsingCss->value['width'];
5952
-            $h = $this->parsingCss->value['height'];
5953
-
5954
-            if (!$this->parsingCss->value['position']) {
5955
-                if (
5956
-                    $w < ($this->pdf->getW() - $this->pdf->getlMargin()-$this->pdf->getrMargin()) &&
5957
-                    $this->pdf->getX() + $w>=($this->pdf->getW() - $this->pdf->getrMargin())
5958
-                    )
5959
-                    $this->_tag_open_BR(array());
5960
-
5961
-                if (
5962
-                        ($h < ($this->pdf->getH() - $this->pdf->gettMargin()-$this->pdf->getbMargin())) &&
5963
-                        ($this->pdf->getY() + $h>=($this->pdf->getH() - $this->pdf->getbMargin())) &&
5964
-                        !$this->_isInOverflow
5965
-                    )
5966
-                    $this->_setNewPage();
5967
-
5968
-                $old = $this->parsingCss->getOldValues();
5969
-                $parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
5970
-
5971
-                if ($parentWidth>$w) {
5972
-                    if ($alignObject=='center')        $this->pdf->setX($this->pdf->getX() + ($parentWidth-$w)*0.5);
5973
-                    else if ($alignObject=='right')    $this->pdf->setX($this->pdf->getX() + $parentWidth-$w);
5974
-                }
5975
-
5976
-                $this->parsingCss->setPosition();
5977
-            } else {
5978
-                $old = $this->parsingCss->getOldValues();
5979
-                $parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
5980
-
5981
-                if ($parentWidth>$w) {
5982
-                    if ($alignObject=='center')        $this->pdf->setX($this->pdf->getX() + ($parentWidth-$w)*0.5);
5983
-                    else if ($alignObject=='right')    $this->pdf->setX($this->pdf->getX() + $parentWidth-$w);
5984
-                }
5985
-
5986
-                $this->parsingCss->setPosition();
5987
-                $this->_saveMax();
5988
-                $this->_maxX = 0;
5989
-                $this->_maxY = 0;
5990
-                $this->_maxH = 0;
5991
-                $this->_maxE = 0;
5992
-            }
5993
-
5994
-            $this->_drawRectangle(
5995
-                $this->parsingCss->value['x'],
5996
-                $this->parsingCss->value['y'],
5997
-                $this->parsingCss->value['width'],
5998
-                $this->parsingCss->value['height'],
5999
-                $this->parsingCss->value['border'],
6000
-                $this->parsingCss->value['padding'],
6001
-                0,
6002
-                $this->parsingCss->value['background']
6003
-            );
6004
-
6005
-            $marge = array();
6006
-            $marge['l'] = $this->parsingCss->value['border']['l']['width'];
6007
-            $marge['r'] = $this->parsingCss->value['border']['r']['width'];
6008
-            $marge['t'] = $this->parsingCss->value['border']['t']['width'];
6009
-            $marge['b'] = $this->parsingCss->value['border']['b']['width'];
6010
-
6011
-            $this->parsingCss->value['width'] -= $marge['l']+$marge['r'];
6012
-            $this->parsingCss->value['height']-= $marge['t']+$marge['b'];
6013
-
6014
-            $overW-= $marge['l']+$marge['r'];
6015
-            $overH-= $marge['t']+$marge['b'];
6016
-
6017
-            // clipping to draw only in the size opf the DRAW tag
6018
-            $this->pdf->clippingPathStart(
6019
-                $this->parsingCss->value['x']+$marge['l'],
6020
-                $this->parsingCss->value['y']+$marge['t'],
6021
-                $this->parsingCss->value['width'],
6022
-                $this->parsingCss->value['height']
6023
-            );
6024
-
6025
-            // left and right of the DRAW tag
6026
-            $mL = $this->parsingCss->value['x']+$marge['l'];
6027
-            $mR = $this->pdf->getW() - $mL - $overW;
6028
-
6029
-            // position of the DRAW tag
6030
-            $x = $this->parsingCss->value['x']+$marge['l'];
6031
-            $y = $this->parsingCss->value['y']+$marge['t'];
6032
-
6033
-            // prepare the drawing area
6034
-            $this->_saveMargin($mL, 0, $mR);
6035
-            $this->pdf->setXY($x, $y);
6036
-
6037
-            // we are in a draw tag
6038
-            $this->_isInDraw = array(
6039
-                'x' => $x,
6040
-                'y' => $y,
6041
-                'w' => $overW,
6042
-                'h' => $overH,
6043
-            );
6044
-
6045
-            // init the translate matrix : (0,0) => ($x, $y)
6046
-            $this->pdf->doTransform(array(1,0,0,1,$x,$y));
6047
-            $this->pdf->SetAlpha(1.);
6048
-            return true;
6049
-        }
6050
-
6051
-        /**
6052
-         * tag : DRAW
6053
-         * mode : CLOSE
6054
-         *
6055
-         * @param  array $param
6056
-         * @return boolean
6057
-         */
6058
-        protected function _tag_close_DRAW($param)
6059
-        {
6060
-            if ($this->_isForOneLine) return false;
6061
-
6062
-            $this->pdf->SetAlpha(1.);
6063
-            $this->pdf->undoTransform();
6064
-            $this->pdf->clippingPathStop();
6065
-
6066
-            $this->_maxX = $this->parsingCss->value['old_maxX'];
6067
-            $this->_maxY = $this->parsingCss->value['old_maxY'];
6068
-            $this->_maxH = $this->parsingCss->value['old_maxH'];
6069
-
6070
-            $marge = array();
6071
-            $marge['l'] = $this->parsingCss->value['border']['l']['width'];
6072
-            $marge['r'] = $this->parsingCss->value['border']['r']['width'];
6073
-            $marge['t'] = $this->parsingCss->value['border']['t']['width'];
6074
-            $marge['b'] = $this->parsingCss->value['border']['b']['width'];
6075
-
6076
-            $x = $this->parsingCss->value['x'];
6077
-            $y = $this->parsingCss->value['y'];
6078
-            $w = $this->parsingCss->value['width']+$marge['l']+$marge['r'];
6079
-            $h = $this->parsingCss->value['height']+$marge['t']+$marge['b'];
6080
-
6081
-            if ($this->parsingCss->value['position']!='absolute') {
6082
-                $this->pdf->setXY($x+$w, $y);
6083
-
6084
-                $this->_maxX = max($this->_maxX, $x+$w);
6085
-                $this->_maxY = max($this->_maxY, $y+$h);
6086
-                $this->_maxH = max($this->_maxH, $h);
6087
-                $this->_maxE++;
6088
-            } else {
6089
-                // position
6090
-                $this->pdf->setXY($this->parsingCss->value['xc'], $this->parsingCss->value['yc']);
6091
-
6092
-                $this->_loadMax();
6093
-            }
6094
-
6095
-            $block = ($this->parsingCss->value['display']!='inline' && $this->parsingCss->value['position']!='absolute');
6096
-
6097
-            $this->parsingCss->load();
6098
-            $this->parsingCss->fontSet();
6099
-            $this->_loadMargin();
6100
-
6101
-            if ($block) $this->_tag_open_BR(array());
6102
-            if ($this->_debugActif) $this->_DEBUG_add('DRAW', false);
6103
-
6104
-            $this->_isInDraw = null;
6105
-
6106
-            return true;
6107
-        }
6108
-
6109
-        /**
6110
-         * tag : LINE
6111
-         * mode : OPEN
6112
-         *
6113
-         * @param  array $param
6114
-         * @return boolean
6115
-         */
6116
-        protected function _tag_open_LINE($param)
6117
-        {
6118
-            if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'LINE');
6119
-
6120
-            $this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6121
-            $this->parsingCss->save();
6122
-            $styles = $this->parsingCss->getSvgStyle('path', $param);
6123
-            $styles['fill'] = null;
6124
-            $style = $this->pdf->svgSetStyle($styles);
6125
-
6126
-            $x1 = isset($param['x1']) ? $this->parsingCss->ConvertToMM($param['x1'], $this->_isInDraw['w']) : 0.;
6127
-            $y1 = isset($param['y1']) ? $this->parsingCss->ConvertToMM($param['y1'], $this->_isInDraw['h']) : 0.;
6128
-            $x2 = isset($param['x2']) ? $this->parsingCss->ConvertToMM($param['x2'], $this->_isInDraw['w']) : 0.;
6129
-            $y2 = isset($param['y2']) ? $this->parsingCss->ConvertToMM($param['y2'], $this->_isInDraw['h']) : 0.;
6130
-            $this->pdf->svgLine($x1, $y1, $x2, $y2);
6131
-
6132
-            $this->pdf->undoTransform();
6133
-            $this->parsingCss->load();
6134
-        }
6135
-
6136
-        /**
6137
-         * tag : RECT
6138
-         * mode : OPEN
6139
-         *
6140
-         * @param  array $param
6141
-         * @return boolean
6142
-         */
6143
-        protected function _tag_open_RECT($param)
6144
-        {
6145
-            if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'RECT');
6146
-
6147
-            $this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6148
-            $this->parsingCss->save();
6149
-            $styles = $this->parsingCss->getSvgStyle('path', $param);
6150
-            $style = $this->pdf->svgSetStyle($styles);
6151
-
6152
-            $x = isset($param['x']) ? $this->parsingCss->ConvertToMM($param['x'], $this->_isInDraw['w']) : 0.;
6153
-            $y = isset($param['y']) ? $this->parsingCss->ConvertToMM($param['y'], $this->_isInDraw['h']) : 0.;
6154
-            $w = isset($param['w']) ? $this->parsingCss->ConvertToMM($param['w'], $this->_isInDraw['w']) : 0.;
6155
-            $h = isset($param['h']) ? $this->parsingCss->ConvertToMM($param['h'], $this->_isInDraw['h']) : 0.;
6156
-
6157
-            $this->pdf->svgRect($x, $y, $w, $h, $style);
6158
-
6159
-            $this->pdf->undoTransform();
6160
-            $this->parsingCss->load();
6161
-        }
6162
-
6163
-        /**
6164
-         * tag : CIRCLE
6165
-         * mode : OPEN
6166
-         *
6167
-         * @param  array $param
6168
-         * @return boolean
6169
-         */
6170
-        protected function _tag_open_CIRCLE($param)
6171
-        {
6172
-            if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'CIRCLE');
6173
-
6174
-            $this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6175
-            $this->parsingCss->save();
6176
-            $styles = $this->parsingCss->getSvgStyle('path', $param);
6177
-            $style = $this->pdf->svgSetStyle($styles);
6178
-
6179
-            $cx = isset($param['cx']) ? $this->parsingCss->ConvertToMM($param['cx'], $this->_isInDraw['w']) : 0.;
6180
-            $cy = isset($param['cy']) ? $this->parsingCss->ConvertToMM($param['cy'], $this->_isInDraw['h']) : 0.;
6181
-            $r = isset($param['r']) ? $this->parsingCss->ConvertToMM($param['r'], $this->_isInDraw['w']) : 0.;
6182
-            $this->pdf->svgEllipse($cx, $cy, $r, $r, $style);
6183
-
6184
-            $this->pdf->undoTransform();
6185
-            $this->parsingCss->load();
6186
-        }
6187
-
6188
-        /**
6189
-         * tag : ELLIPSE
6190
-         * mode : OPEN
6191
-         *
6192
-         * @param  array $param
6193
-         * @return boolean
6194
-         */
6195
-        protected function _tag_open_ELLIPSE($param)
6196
-        {
6197
-            if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'ELLIPSE');
6198
-
6199
-            $this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6200
-            $this->parsingCss->save();
6201
-            $styles = $this->parsingCss->getSvgStyle('path', $param);
6202
-            $style = $this->pdf->svgSetStyle($styles);
6203
-
6204
-            $cx = isset($param['cx']) ? $this->parsingCss->ConvertToMM($param['cx'], $this->_isInDraw['w']) : 0.;
6205
-            $cy = isset($param['cy']) ? $this->parsingCss->ConvertToMM($param['cy'], $this->_isInDraw['h']) : 0.;
6206
-            $rx = isset($param['ry']) ? $this->parsingCss->ConvertToMM($param['rx'], $this->_isInDraw['w']) : 0.;
6207
-            $ry = isset($param['rx']) ? $this->parsingCss->ConvertToMM($param['ry'], $this->_isInDraw['h']) : 0.;
6208
-            $this->pdf->svgEllipse($cx, $cy, $rx, $ry, $style);
6209
-
6210
-            $this->pdf->undoTransform();
6211
-            $this->parsingCss->load();
6212
-        }
6213
-
6214
-
6215
-        /**
6216
-         * tag : POLYLINE
6217
-         * mode : OPEN
6218
-         *
6219
-         * @param  array $param
6220
-         * @return boolean
6221
-         */
6222
-        protected function _tag_open_POLYLINE($param)
6223
-        {
6224
-            if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'POLYGON');
6225
-
6226
-            $this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6227
-            $this->parsingCss->save();
6228
-            $styles = $this->parsingCss->getSvgStyle('path', $param);
6229
-            $style = $this->pdf->svgSetStyle($styles);
6230
-
6231
-            $path = isset($param['points']) ? $param['points'] : null;
6232
-            if ($path) {
6233
-                $path = str_replace(',', ' ', $path);
6234
-                $path = preg_replace('/[\s]+/', ' ', trim($path));
6235
-
6236
-                // prepare the path
6237
-                $path = explode(' ', $path);
6238
-                foreach ($path as $k => $v) {
6239
-                    $path[$k] = trim($v);
6240
-                    if ($path[$k]==='') unset($path[$k]);
6241
-                }
6242
-                $path = array_values($path);
6243
-
6244
-                $actions = array();
6245
-                for ($k=0; $k<count($path); $k+=2) {
6246
-                    $actions[] = array(
6247
-                        ($k ? 'L' : 'M') ,
6248
-                        $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']),
6249
-                        $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h'])
6250
-                    );
6251
-                }
6252
-
6253
-                // drawing
6254
-                $this->pdf->svgPolygone($actions, $style);
6255
-            }
6256
-
6257
-            $this->pdf->undoTransform();
6258
-            $this->parsingCss->load();
6259
-        }
6260
-
6261
-        /**
6262
-         * tag : POLYGON
6263
-         * mode : OPEN
6264
-         *
6265
-         * @param  array $param
6266
-         * @return boolean
6267
-         */
6268
-        protected function _tag_open_POLYGON($param)
6269
-        {
6270
-            if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'POLYGON');
6271
-
6272
-            $this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6273
-            $this->parsingCss->save();
6274
-            $styles = $this->parsingCss->getSvgStyle('path', $param);
6275
-            $style = $this->pdf->svgSetStyle($styles);
6276
-
6277
-            $path = (isset($param['points']) ? $param['points'] : null);
6278
-            if ($path) {
6279
-                $path = str_replace(',', ' ', $path);
6280
-                $path = preg_replace('/[\s]+/', ' ', trim($path));
6281
-
6282
-                // prepare the path
6283
-                $path = explode(' ', $path);
6284
-                foreach ($path as $k => $v) {
6285
-                    $path[$k] = trim($v);
6286
-                    if ($path[$k]==='') unset($path[$k]);
6287
-                }
6288
-                $path = array_values($path);
6289
-
6290
-                $actions = array();
6291
-                for ($k=0; $k<count($path); $k+=2) {
6292
-                    $actions[] = array(
6293
-                        ($k ? 'L' : 'M') ,
6294
-                        $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']),
6295
-                        $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h'])
6296
-                    );
6297
-                }
6298
-                $actions[] = array('z');
6299
-
6300
-                // drawing
6301
-                $this->pdf->svgPolygone($actions, $style);
6302
-            }
6303
-
6304
-            $this->pdf->undoTransform();
6305
-            $this->parsingCss->load();
6306
-        }
6307
-
6308
-        /**
6309
-         * tag : PATH
6310
-         * mode : OPEN
6311
-         *
6312
-         * @param  array $param
6313
-         * @return boolean
6314
-         */
6315
-        protected function _tag_open_PATH($param)
6316
-        {
6317
-            if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'PATH');
6318
-
6319
-            $this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6320
-            $this->parsingCss->save();
6321
-            $styles = $this->parsingCss->getSvgStyle('path', $param);
6322
-            $style = $this->pdf->svgSetStyle($styles);
6323
-
6324
-            $path = isset($param['d']) ? $param['d'] : null;
6325
-
6326
-            if ($path) {
6327
-                // prepare the path
6328
-                $path = str_replace(',', ' ', $path);
6329
-                $path = preg_replace('/([a-zA-Z])([0-9\.\-])/', '$1 $2', $path);
6330
-                $path = preg_replace('/([0-9\.])([a-zA-Z])/', '$1 $2', $path);
6331
-                $path = preg_replace('/[\s]+/', ' ', trim($path));
6332
-                $path = preg_replace('/ ([a-z]{2})/', '$1', $path);
6333
-
6334
-                $path = explode(' ', $path);
6335
-                foreach ($path as $k => $v) {
6336
-                    $path[$k] = trim($v);
6337
-                    if ($path[$k]==='') unset($path[$k]);
6338
-                }
6339
-                $path = array_values($path);
6340
-
6341
-                // read each actions in the path
6342
-                $actions = array();
6343
-                $action = array();
6344
-                $lastAction = null; // last action found
6345
-                for ($k=0; $k<count($path);true) {
6346
-
6347
-                    // for this actions, we can not have multi coordonate
6348
-                    if (in_array($lastAction, array('z', 'Z'))) {
6349
-                        $lastAction = null;
6350
-                    }
6351
-
6352
-                    // read the new action (forcing if no action before)
6353
-                    if (preg_match('/^[a-z]+$/i', $path[$k]) || $lastAction===null) {
6354
-                        $lastAction = $path[$k];
6355
-                        $k++;
6356
-                    }
6357
-
6358
-                    // current action
6359
-                    $action = array();
6360
-                    $action[] = $lastAction;
6361
-                    switch($lastAction)
6362
-                    {
6363
-                        case 'C':
6364
-                        case 'c':
6365
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // x1
6366
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h']);    // y1
6367
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+2], $this->_isInDraw['w']);    // x2
6368
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+3], $this->_isInDraw['h']);    // y2
6369
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+4], $this->_isInDraw['w']);    // x
6370
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+5], $this->_isInDraw['h']);    // y
6371
-                            $k+= 6;
6372
-                            break;
6373
-
6374
-                        case 'Q':
6375
-                        case 'S':
6376
-                        case 'q':
6377
-                        case 's':
6378
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // x2
6379
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h']);    // y2
6380
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+2], $this->_isInDraw['w']);    // x
6381
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+3], $this->_isInDraw['h']);    // y
6382
-                            $k+= 4;
6383
-                            break;
6384
-
6385
-                        case 'A':
6386
-                        case 'a':
6387
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // rx
6388
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h']);    // ry
6389
-                            $action[] = 1.*$path[$k+2];                                                        // angle de deviation de l'axe X
6390
-                            $action[] = ($path[$k+3]=='1') ? 1 : 0;                                            // large-arc-flag
6391
-                            $action[] = ($path[$k+4]=='1') ? 1 : 0;                                            // sweep-flag
6392
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+5], $this->_isInDraw['w']);    // x
6393
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+6], $this->_isInDraw['h']);    // y
6394
-                            $k+= 7;
6395
-                            break;
6396
-
6397
-                        case 'M':
6398
-                        case 'L':
6399
-                        case 'T':
6400
-                        case 'm':
6401
-                        case 'l':
6402
-                        case 't':
6403
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // x
6404
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h']);    // y
6405
-                            $k+= 2;
6406
-                            break;
6407
-
6408
-                        case 'H':
6409
-                        case 'h':
6410
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // x
6411
-                            $k+= 1;
6412
-                            break;
6413
-
6414
-                        case 'V':
6415
-                        case 'v':
6416
-                            $action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['h']);    // y
6417
-                            $k+= 1;
6418
-                            break;
6419
-
6420
-                        case 'z':
6421
-                        case 'Z':
6422
-                        default:
6423
-                            break;
6424
-                    }
6425
-                    // add the action
6426
-                    $actions[] = $action;
6427
-                }
6428
-
6429
-                // drawing
6430
-                $this->pdf->svgPolygone($actions, $style);
6431
-            }
6432
-
6433
-            $this->pdf->undoTransform();
6434
-            $this->parsingCss->load();
6435
-        }
6436
-
6437
-        /**
6438
-         * tag : G
6439
-         * mode : OPEN
6440
-         *
6441
-         * @param  array $param
6442
-         * @return boolean
6443
-         */
6444
-        protected function _tag_open_G($param)
6445
-        {
6446
-            if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'G');
6447
-
6448
-            $this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6449
-            $this->parsingCss->save();
6450
-            $styles = $this->parsingCss->getSvgStyle('path', $param);
6451
-            $style = $this->pdf->svgSetStyle($styles);
6452
-        }
6453
-
6454
-        /**
6455
-         * tag : G
6456
-         * mode : CLOSE
6457
-         *
6458
-         * @param  array $param
6459
-         * @return boolean
6460
-         */
6461
-        protected function _tag_close_G($param)
6462
-        {
6463
-            $this->pdf->undoTransform();
6464
-            $this->parsingCss->load();
6465
-        }
6466
-
6467
-        /**
6468
-         * new page for the automatic Index, does not use thie method. Only HTML2PDF_myPdf could use it !!!!
6469
-         *
6470
-         * @param  &int $page
6471
-         * @return integer $oldPage
6472
-         */
6473
-        public function _INDEX_NewPage(&$page)
6474
-        {
6475
-            if ($page) {
6476
-                $oldPage = $this->pdf->getPage();
6477
-                $this->pdf->setPage($page);
6478
-                $this->pdf->setXY($this->_margeLeft, $this->_margeTop);
6479
-                $this->_maxH = 0;
6480
-                $page++;
6481
-                return $oldPage;
6482
-            } else {
6483
-                $this->_setNewPage();
6484
-                return null;
6485
-            }
6486
-        }
6487
-
6488
-    }
501
+			exit;
502
+		}
503
+
504
+		/**
505
+		 * set the default margins of the page
506
+		 *
507
+		 * @access protected
508
+		 * @param  int $left   (mm, left margin)
509
+		 * @param  int $top    (mm, top margin)
510
+		 * @param  int $right  (mm, right margin, if null => left=right)
511
+		 * @param  int $bottom (mm, bottom margin, if null => bottom=8mm)
512
+		 */
513
+		protected function _setDefaultMargins($left, $top, $right = null, $bottom = null)
514
+		{
515
+			if ($right===null)  $right = $left;
516
+			if ($bottom===null) $bottom = 8;
517
+
518
+			$this->_defaultLeft   = $this->parsingCss->ConvertToMM($left.'mm');
519
+			$this->_defaultTop    = $this->parsingCss->ConvertToMM($top.'mm');
520
+			$this->_defaultRight  = $this->parsingCss->ConvertToMM($right.'mm');
521
+			$this->_defaultBottom = $this->parsingCss->ConvertToMM($bottom.'mm');
522
+		}
523
+
524
+		/**
525
+		 * create a new page
526
+		 *
527
+		 * @access protected
528
+		 * @param  mixed   $format
529
+		 * @param  string  $orientation
530
+		 * @param  array   $background background information
531
+		 * @param  integer $curr real position in the html parseur (if break line in the write of a text)
532
+		 * @param  boolean $resetPageNumber
533
+		 */
534
+		protected function _setNewPage($format = null, $orientation = '', $background = null, $curr = null, $resetPageNumber=false)
535
+		{
536
+			$this->_firstPage = false;
537
+
538
+			$this->_format = $format ? $format : $this->_format;
539
+			$this->_orientation = $orientation ? $orientation : $this->_orientation;
540
+			$this->_background = $background!==null ? $background : $this->_background;
541
+			$this->_maxY = 0;
542
+			$this->_maxX = 0;
543
+			$this->_maxH = 0;
544
+			$this->_maxE = 0;
545
+
546
+			$this->pdf->SetMargins($this->_defaultLeft, $this->_defaultTop, $this->_defaultRight);
547
+
548
+			if ($resetPageNumber) {
549
+				$this->pdf->startPageGroup();
550
+			}
551
+
552
+			$this->pdf->AddPage($this->_orientation, $this->_format);
553
+
554
+			if ($resetPageNumber) {
555
+				$this->pdf->myStartPageGroup();
556
+			}
557
+
558
+			$this->_page++;
559
+
560
+			if (!$this->_subPart && !$this->_isSubPart) {
561
+				if (is_array($this->_background)) {
562
+					if (isset($this->_background['color']) && $this->_background['color']) {
563
+						$this->pdf->setFillColorArray($this->_background['color']);
564
+						$this->pdf->Rect(0, 0, $this->pdf->getW(), $this->pdf->getH(), 'F');
565
+					}
566
+
567
+					if (isset($this->_background['img']) && $this->_background['img'])
568
+						$this->pdf->Image($this->_background['img'], $this->_background['posX'], $this->_background['posY'], $this->_background['width']);
569
+				}
570
+
571
+				$this->_setPageHeader();
572
+				$this->_setPageFooter();
573
+			}
574
+
575
+			$this->_setMargins();
576
+			$this->pdf->setY($this->_margeTop);
577
+
578
+			$this->_setNewPositionForNewLine($curr);
579
+			$this->_maxH = 0;
580
+		}
581
+
582
+		/**
583
+		 * set the real margin, using the default margins and the page margins
584
+		 *
585
+		 * @access protected
586
+		 */
587
+		protected function _setMargins()
588
+		{
589
+			// prepare the margins
590
+			$this->_margeLeft   = $this->_defaultLeft   + (isset($this->_background['left'])   ? $this->_background['left']   : 0);
591
+			$this->_margeRight  = $this->_defaultRight  + (isset($this->_background['right'])  ? $this->_background['right']  : 0);
592
+			$this->_margeTop    = $this->_defaultTop    + (isset($this->_background['top'])    ? $this->_background['top']    : 0);
593
+			$this->_margeBottom = $this->_defaultBottom + (isset($this->_background['bottom']) ? $this->_background['bottom'] : 0);
594
+
595
+			// set the PDF margins
596
+			$this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
597
+			$this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
598
+
599
+			// set the float Margins
600
+			$this->_pageMarges = array();
601
+			if ($this->_isInParagraph!==false) {
602
+				$this->_pageMarges[floor($this->_margeTop*100)] = array($this->_isInParagraph[0], $this->pdf->getW()-$this->_isInParagraph[1]);
603
+			} else {
604
+				$this->_pageMarges[floor($this->_margeTop*100)] = array($this->_margeLeft, $this->pdf->getW()-$this->_margeRight);
605
+			}
606
+		}
607
+
608
+		/**
609
+		 * add a debug step
610
+		 *
611
+		 * @access protected
612
+		 * @param  string  $name step name
613
+		 * @param  boolean $level (true=up, false=down, null=nothing to do)
614
+		 * @return $this
615
+		 */
616
+		protected function _DEBUG_add($name, $level=null)
617
+		{
618
+			// if true : UP
619
+			if ($level===true) $this->_debugLevel++;
620
+
621
+			$name   = str_repeat('  ', $this->_debugLevel). $name.($level===true ? ' Begin' : ($level===false ? ' End' : ''));
622
+			$time  = microtime(true);
623
+			$usage = ($this->_debugOkUsage ? memory_get_usage() : 0);
624
+			$peak  = ($this->_debugOkPeak ? memory_get_peak_usage() : 0);
625
+
626
+			$this->_DEBUG_stepline(
627
+				$name,
628
+				number_format(($time - $this->_debugStartTime)*1000, 1, '.', ' ').' ms',
629
+				number_format(($time - $this->_debugLastTime)*1000, 1, '.', ' ').' ms',
630
+				number_format($usage/1024, 1, '.', ' ').' Ko',
631
+				number_format($peak/1024, 1, '.', ' ').' Ko'
632
+			);
633
+
634
+			$this->_debugLastTime = $time;
635
+
636
+			// it false : DOWN
637
+			if ($level===false) $this->_debugLevel--;
638
+
639
+			return $this;
640
+		}
641
+
642
+		/**
643
+		 * display a debug line
644
+		 *
645
+		 *
646
+		 * @access protected
647
+		 * @param  string $name
648
+		 * @param  string $timeTotal
649
+		 * @param  string $timeStep
650
+		 * @param  string $memoryUsage
651
+		 * @param  string $memoryPeak
652
+		 */
653
+		protected function _DEBUG_stepline($name, $timeTotal, $timeStep, $memoryUsage, $memoryPeak)
654
+		{
655
+			$txt = str_pad($name, 30, ' ', STR_PAD_RIGHT).
656
+					str_pad($timeTotal, 12, ' ', STR_PAD_LEFT).
657
+					str_pad($timeStep, 12, ' ', STR_PAD_LEFT).
658
+					str_pad($memoryUsage, 15, ' ', STR_PAD_LEFT).
659
+					str_pad($memoryPeak, 15, ' ', STR_PAD_LEFT);
660
+
661
+			echo '<pre style="padding:0; margin:0">'.$txt.'</pre>';
662
+		}
663
+
664
+		/**
665
+		 * get the Min and Max X, for Y (use the float margins)
666
+		 *
667
+		 * @access protected
668
+		 * @param  float $y
669
+		 * @return array(float, float)
670
+		 */
671
+		protected function _getMargins($y)
672
+		{
673
+			$y = floor($y*100);
674
+			$x = array($this->pdf->getlMargin(), $this->pdf->getW()-$this->pdf->getrMargin());
675
+
676
+			foreach ($this->_pageMarges as $mY => $mX)
677
+				if ($mY<=$y) $x = $mX;
678
+
679
+			return $x;
680
+		}
681
+
682
+		/**
683
+		 * Add margins, for a float
684
+		 *
685
+		 * @access protected
686
+		 * @param  string $float (left / right)
687
+		 * @param  float  $xLeft
688
+		 * @param  float  $yTop
689
+		 * @param  float  $xRight
690
+		 * @param  float  $yBottom
691
+		 */
692
+		protected function _addMargins($float, $xLeft, $yTop, $xRight, $yBottom)
693
+		{
694
+			// get the current float margins, for top and bottom
695
+			$oldTop    = $this->_getMargins($yTop);
696
+			$oldBottom = $this->_getMargins($yBottom);
697
+
698
+			// update the top float margin
699
+			if ($float=='left'  && $oldTop[0]<$xRight) $oldTop[0] = $xRight;
700
+			if ($float=='right' && $oldTop[1]>$xLeft)  $oldTop[1] = $xLeft;
701
+
702
+			$yTop = floor($yTop*100);
703
+			$yBottom = floor($yBottom*100);
704
+
705
+			// erase all the float margins that are smaller than the new one
706
+			foreach ($this->_pageMarges as $mY => $mX) {
707
+				if ($mY<$yTop) continue;
708
+				if ($mY>$yBottom) break;
709
+				if ($float=='left' && $this->_pageMarges[$mY][0]<$xRight)  unset($this->_pageMarges[$mY]);
710
+				if ($float=='right' && $this->_pageMarges[$mY][1]>$xLeft) unset($this->_pageMarges[$mY]);
711
+			}
712
+
713
+			// save the new Top and Bottom margins
714
+			$this->_pageMarges[$yTop] = $oldTop;
715
+			$this->_pageMarges[$yBottom] = $oldBottom;
716
+
717
+			// sort the margins
718
+			ksort($this->_pageMarges);
719
+
720
+			// we are just after float
721
+			$this->_isAfterFloat = true;
722
+		}
723
+
724
+		/**
725
+		 * Save old margins (push), and set new ones
726
+		 *
727
+		 * @access protected
728
+		 * @param  float  $ml left margin
729
+		 * @param  float  $mt top margin
730
+		 * @param  float  $mr right margin
731
+		 */
732
+		protected function _saveMargin($ml, $mt, $mr)
733
+		{
734
+			// save old margins
735
+			$this->_marges[] = array('l' => $this->pdf->getlMargin(), 't' => $this->pdf->gettMargin(), 'r' => $this->pdf->getrMargin(), 'page' => $this->_pageMarges);
736
+
737
+			// set new ones
738
+			$this->pdf->SetMargins($ml, $mt, $mr);
739
+
740
+			// prepare for float margins
741
+			$this->_pageMarges = array();
742
+			$this->_pageMarges[floor($mt*100)] = array($ml, $this->pdf->getW()-$mr);
743
+		}
744
+
745
+		/**
746
+		 * load the last saved margins (pop)
747
+		 *
748
+		 * @access protected
749
+		 */
750
+		protected function _loadMargin()
751
+		{
752
+			$old = array_pop($this->_marges);
753
+			if ($old) {
754
+				$ml = $old['l'];
755
+				$mt = $old['t'];
756
+				$mr = $old['r'];
757
+				$mP = $old['page'];
758
+			} else {
759
+				$ml = $this->_margeLeft;
760
+				$mt = 0;
761
+				$mr = $this->_margeRight;
762
+				$mP = array($mt => array($ml, $this->pdf->getW()-$mr));
763
+			}
764
+
765
+			$this->pdf->SetMargins($ml, $mt, $mr);
766
+			$this->_pageMarges = $mP;
767
+		}
768
+
769
+		/**
770
+		 * save the current maxs (push)
771
+		 *
772
+		 * @access protected
773
+		 */
774
+		protected function _saveMax()
775
+		{
776
+			$this->_maxSave[] = array($this->_maxX, $this->_maxY, $this->_maxH, $this->_maxE);
777
+		}
778
+
779
+		/**
780
+		 * load the last saved current maxs (pop)
781
+		 *
782
+		 * @access protected
783
+		 */
784
+		protected function _loadMax()
785
+		{
786
+			$old = array_pop($this->_maxSave);
787
+
788
+			if ($old) {
789
+				$this->_maxX = $old[0];
790
+				$this->_maxY = $old[1];
791
+				$this->_maxH = $old[2];
792
+				$this->_maxE = $old[3];
793
+			} else {
794
+				$this->_maxX = 0;
795
+				$this->_maxY = 0;
796
+				$this->_maxH = 0;
797
+				$this->_maxE = 0;
798
+			}
799
+		}
800
+
801
+		/**
802
+		 * draw the PDF header with the HTML in page_header
803
+		 *
804
+		 * @access protected
805
+		 */
806
+		protected function _setPageHeader()
807
+		{
808
+			if (!count($this->_subHEADER)) return false;
809
+
810
+			$oldParsePos = $this->_parsePos;
811
+			$oldParseCode = $this->parsingHtml->code;
812
+
813
+			$this->_parsePos = 0;
814
+			$this->parsingHtml->code = $this->_subHEADER;
815
+			$this->_makeHTMLcode();
816
+
817
+			$this->_parsePos = $oldParsePos;
818
+			$this->parsingHtml->code = $oldParseCode;
819
+		}
820
+
821
+		/**
822
+		 * draw the PDF footer with the HTML in page_footer
823
+		 *
824
+		 * @access protected
825
+		 */
826
+		protected function _setPageFooter()
827
+		{
828
+			if (!count($this->_subFOOTER)) return false;
829
+
830
+			$oldParsePos = $this->_parsePos;
831
+			$oldParseCode = $this->parsingHtml->code;
832
+
833
+			$this->_parsePos = 0;
834
+			$this->parsingHtml->code = $this->_subFOOTER;
835
+			$this->_isInFooter = true;
836
+			$this->_makeHTMLcode();
837
+			$this->_isInFooter = false;
838
+
839
+			$this->_parsePos = $oldParsePos;
840
+			$this->parsingHtml->code = $oldParseCode;
841
+		}
842
+
843
+		/**
844
+		 * new line, with a specific height
845
+		 *
846
+		 * @access protected
847
+		 * @param float   $h
848
+		 * @param integer $curr real current position in the text, if new line in the write of a text
849
+		 */
850
+		protected function _setNewLine($h, $curr = null)
851
+		{
852
+			$this->pdf->Ln($h);
853
+			$this->_setNewPositionForNewLine($curr);
854
+		}
855
+
856
+		/**
857
+		 * calculate the start position of the next line,  depending on the text-align
858
+		 *
859
+		 * @access protected
860
+		 * @param  integer $curr real current position in the text, if new line in the write of a text
861
+		 */
862
+		protected function _setNewPositionForNewLine($curr = null)
863
+		{
864
+			// get the margins for the current line
865
+			list($lx, $rx) = $this->_getMargins($this->pdf->getY());
866
+			$this->pdf->setX($lx);
867
+			$wMax = $rx-$lx;
868
+			$this->_currentH = 0;
869
+
870
+			// if subPart => return because align left
871
+			if ($this->_subPart || $this->_isSubPart || $this->_isForOneLine) {
872
+				$this->pdf->setWordSpacing(0);
873
+				return null;
874
+			}
875
+
876
+			// create the sub object
877
+			$sub = null;
878
+			$this->_createSubHTML($sub);
879
+			$sub->_saveMargin(0, 0, $sub->pdf->getW()-$wMax);
880
+			$sub->_isForOneLine = true;
881
+			$sub->_parsePos = $this->_parsePos;
882
+			$sub->parsingHtml->code = $this->parsingHtml->code;
883
+
884
+			// if $curr => adapt the current position of the parsing
885
+			if ($curr!==null && $sub->parsingHtml->code[$this->_parsePos]['name']=='write') {
886
+				$txt = $sub->parsingHtml->code[$this->_parsePos]['param']['txt'];
887
+				$txt = str_replace('[[page_cu]]', $sub->pdf->getMyNumPage($this->_page), $txt);
888
+				$sub->parsingHtml->code[$this->_parsePos]['param']['txt'] = substr($txt, $curr+1);
889
+			} else
890
+				$sub->_parsePos++;
891
+
892
+			// for each element of the parsing => load the action
893
+			$res = null;
894
+			for ($sub->_parsePos; $sub->_parsePos<count($sub->parsingHtml->code); $sub->_parsePos++) {
895
+				$action = $sub->parsingHtml->code[$sub->_parsePos];
896
+				$res = $sub->_executeAction($action);
897
+				if (!$res) break;
898
+			}
899
+
900
+			$w = $sub->_maxX; // max width
901
+			$h = $sub->_maxH; // max height
902
+			$e = ($res===null ? $sub->_maxE : 0); // maxnumber of elemets on the line
903
+
904
+			// destroy the sub HTML
905
+			$this->_destroySubHTML($sub);
906
+
907
+			// adapt the start of the line, depending on the text-align
908
+			if ($this->parsingCss->value['text-align']=='center')
909
+				$this->pdf->setX(($rx+$this->pdf->getX()-$w)*0.5-0.01);
910
+			else if ($this->parsingCss->value['text-align']=='right')
911
+				$this->pdf->setX($rx-$w-0.01);
912
+			else
913
+				$this->pdf->setX($lx);
914
+
915
+			// set the height of the line
916
+			$this->_currentH = $h;
917
+
918
+			// if justify => set the word spacing
919
+			if ($this->parsingCss->value['text-align']=='justify' && $e>1) {
920
+				$this->pdf->setWordSpacing(($wMax-$w)/($e-1));
921
+			} else {
922
+				$this->pdf->setWordSpacing(0);
923
+			}
924
+		}
925
+
926
+		/**
927
+		 * prepare HTML2PDF::$_subobj (used for create the sub HTML2PDF objects
928
+		 *
929
+		 * @access protected
930
+		 */
931
+		protected function _prepareSubObj()
932
+		{
933
+			$pdf = null;
934
+
935
+			// create the sub object
936
+			HTML2PDF::$_subobj = new HTML2PDF(
937
+										$this->_orientation,
938
+										$this->_format,
939
+										$this->_langue,
940
+										$this->_unicode,
941
+										$this->_encoding,
942
+										array($this->_defaultLeft,$this->_defaultTop,$this->_defaultRight,$this->_defaultBottom)
943
+									);
944
+
945
+			// init
946
+			HTML2PDF::$_subobj->setTestTdInOnePage($this->_testTdInOnepage);
947
+			HTML2PDF::$_subobj->setTestIsImage($this->_testIsImage);
948
+			HTML2PDF::$_subobj->setTestIsDeprecated($this->_testIsDeprecated);
949
+			HTML2PDF::$_subobj->setDefaultFont($this->_defaultFont);
950
+			HTML2PDF::$_subobj->parsingCss->css            = &$this->parsingCss->css;
951
+			HTML2PDF::$_subobj->parsingCss->cssKeys        = &$this->parsingCss->cssKeys;
952
+
953
+			// clone font from the original PDF
954
+			HTML2PDF::$_subobj->pdf->cloneFontFrom($this->pdf);
955
+
956
+			// remove the link to the parent
957
+			HTML2PDF::$_subobj->parsingCss->setPdfParent($pdf);
958
+		}
959
+
960
+		/**
961
+		 * create a sub HTML2PDF, to calculate the multi-tables
962
+		 *
963
+		 * @access protected
964
+		 * @param  &HTML2PDF $subHtml sub HTML2PDF to create
965
+		 * @param  integer   $cellmargin if in a TD : cellmargin of this td
966
+		 */
967
+		protected function _createSubHTML(&$subHtml, $cellmargin=0)
968
+		{
969
+			// prepare the subObject, if never prepare before
970
+			if (HTML2PDF::$_subobj===null) {
971
+				$this->_prepareSubObj();
972
+			}
973
+
974
+			// calculate the width to use
975
+			if ($this->parsingCss->value['width']) {
976
+				$marge = $cellmargin*2;
977
+				$marge+= $this->parsingCss->value['padding']['l'] + $this->parsingCss->value['padding']['r'];
978
+				$marge+= $this->parsingCss->value['border']['l']['width'] + $this->parsingCss->value['border']['r']['width'];
979
+				$marge = $this->pdf->getW() - $this->parsingCss->value['width'] + $marge;
980
+			} else {
981
+				$marge = $this->_margeLeft+$this->_margeRight;
982
+			}
983
+
984
+			// BUGFIX : we have to call the method, because of a bug in php 5.1.6
985
+			HTML2PDF::$_subobj->pdf->getPage();
986
+
987
+			// clone the sub oject
988
+			$subHtml = clone HTML2PDF::$_subobj;
989
+			$subHtml->parsingCss->table = $this->parsingCss->table;
990
+			$subHtml->parsingCss->value = $this->parsingCss->value;
991
+			$subHtml->initSubHtml(
992
+				$this->_format,
993
+				$this->_orientation,
994
+				$marge,
995
+				$this->_page,
996
+				$this->_defList,
997
+				$this->pdf->getMyLastPageGroup(),
998
+				$this->pdf->getMyLastPageGroupNb()
999
+			);
1000
+		}
1001
+
1002
+		/**
1003
+		 * destroy a subHTML2PDF
1004
+		 *
1005
+		 * @access protected
1006
+		 */
1007
+		protected function _destroySubHTML(&$subHtml)
1008
+		{
1009
+			unset($subHtml);
1010
+			$subHtml = null;
1011
+		}
1012
+
1013
+		/**
1014
+		 * Convert a arabic number in roman number
1015
+		 *
1016
+		 * @access protected
1017
+		 * @param  integer $nbArabic
1018
+		 * @return string  $nbRoman
1019
+		 */
1020
+		protected function _listeArab2Rom($nbArabic)
1021
+		{
1022
+			$nbBaseTen    = array('I','X','C','M');
1023
+			$nbBaseFive    = array('V','L','D');
1024
+			$nbRoman    = '';
1025
+
1026
+			if ($nbArabic<1)    return $nbArabic;
1027
+			if ($nbArabic>3999) return $nbArabic;
1028
+
1029
+			for ($i=3; $i>=0 ; $i--) {
1030
+				$chiffre=floor($nbArabic/pow(10, $i));
1031
+				if ($chiffre>=1) {
1032
+					$nbArabic=$nbArabic-$chiffre*pow(10, $i);
1033
+					if ($chiffre<=3) {
1034
+						for ($j=$chiffre; $j>=1; $j--) {
1035
+							$nbRoman=$nbRoman.$nbBaseTen[$i];
1036
+						}
1037
+					} else if ($chiffre==9) {
1038
+						$nbRoman=$nbRoman.$nbBaseTen[$i].$nbBaseTen[$i+1];
1039
+					} else if ($chiffre==4) {
1040
+					$nbRoman=$nbRoman.$nbBaseTen[$i].$nbBaseFive[$i];
1041
+					} else {
1042
+						$nbRoman=$nbRoman.$nbBaseFive[$i];
1043
+						for ($j=$chiffre-5; $j>=1; $j--) {
1044
+							$nbRoman=$nbRoman.$nbBaseTen[$i];
1045
+						}
1046
+					}
1047
+				}
1048
+			}
1049
+			return $nbRoman;
1050
+		}
1051
+
1052
+		/**
1053
+		 * add a LI to the current level
1054
+		 *
1055
+		 * @access protected
1056
+		 */
1057
+		protected function _listeAddLi()
1058
+		{
1059
+			$this->_defList[count($this->_defList)-1]['nb']++;
1060
+		}
1061
+
1062
+		/**
1063
+		 * get the width to use for the column of the list
1064
+		 *
1065
+		 * @access protected
1066
+		 * @return string $width
1067
+		 */
1068
+		protected function _listeGetWidth()
1069
+		{
1070
+			return '7mm';
1071
+		}
1072
+
1073
+		/**
1074
+		 * get the padding to use for the column of the list
1075
+		 *
1076
+		 * @access protected
1077
+		 * @return string $padding
1078
+		 */
1079
+		protected function _listeGetPadding()
1080
+		{
1081
+			return '1mm';
1082
+		}
1083
+
1084
+		/**
1085
+		 * get the information of the li on the current level
1086
+		 *
1087
+		 * @access protected
1088
+		 * @return array(fontName, small size, string)
1089
+		 */
1090
+		protected function _listeGetLi()
1091
+		{
1092
+			$im = $this->_defList[count($this->_defList)-1]['img'];
1093
+			$st = $this->_defList[count($this->_defList)-1]['style'];
1094
+			$nb = $this->_defList[count($this->_defList)-1]['nb'];
1095
+			$up = (substr($st, 0, 6)=='upper-');
1096
+
1097
+			if ($im) return array(false, false, $im);
1098
+
1099
+			switch($st)
1100
+			{
1101
+				case 'none':
1102
+					return array('helvetica', true, ' ');
1103
+
1104
+				case 'upper-alpha':
1105
+				case 'lower-alpha':
1106
+					$str = '';
1107
+					while ($nb>26) {
1108
+						$str = chr(96+$nb%26).$str;
1109
+						$nb = floor($nb/26);
1110
+					}
1111
+					$str = chr(96+$nb).$str;
1112
+
1113
+					return array('helvetica', false, ($up ? strtoupper($str) : $str).'.');
1114
+
1115
+				case 'upper-roman':
1116
+				case 'lower-roman':
1117
+					$str = $this->_listeArab2Rom($nb);
1118
+
1119
+					return array('helvetica', false, ($up ? strtoupper($str) : $str).'.');
1120
+
1121
+				case 'decimal':
1122
+					return array('helvetica', false, $nb.'.');
1123
+
1124
+				case 'square':
1125
+					return array('zapfdingbats', true, chr(110));
1126
+
1127
+				case 'circle':
1128
+					return array('zapfdingbats', true, chr(109));
1129
+
1130
+				case 'disc':
1131
+				default:
1132
+					return array('zapfdingbats', true, chr(108));
1133
+			}
1134
+		}
1135
+
1136
+		/**
1137
+		 * add a level to the list
1138
+		 *
1139
+		 * @access protected
1140
+		 * @param  string $type  : ul, ol
1141
+		 * @param  string $style : lower-alpha, ...
1142
+		 * @param  string $img
1143
+		 */
1144
+		protected function _listeAddLevel($type = 'ul', $style = '', $img = null)
1145
+		{
1146
+			// get the url of the image, if we want to use a image
1147
+			if ($img) {
1148
+				if (preg_match('/^url\(([^)]+)\)$/isU', trim($img), $match)) {
1149
+					$img = $match[1];
1150
+				} else {
1151
+					$img = null;
1152
+				}
1153
+			} else {
1154
+				$img = null;
1155
+			}
1156
+
1157
+			// prepare the datas
1158
+			if (!in_array($type, array('ul', 'ol'))) $type = 'ul';
1159
+			if (!in_array($style, array('lower-alpha', 'upper-alpha', 'upper-roman', 'lower-roman', 'decimal', 'square', 'circle', 'disc', 'none'))) $style = '';
1160
+
1161
+			if (!$style) {
1162
+				if ($type=='ul')    $style = 'disc';
1163
+				else                $style = 'decimal';
1164
+			}
1165
+
1166
+			// add the new level
1167
+			$this->_defList[count($this->_defList)] = array('style' => $style, 'nb' => 0, 'img' => $img);
1168
+		}
1169
+
1170
+		/**
1171
+		 * remove a level to the list
1172
+		 *
1173
+		 * @access protected
1174
+		 */
1175
+		protected function _listeDelLevel()
1176
+		{
1177
+			if (count($this->_defList)) {
1178
+				unset($this->_defList[count($this->_defList)-1]);
1179
+				$this->_defList = array_values($this->_defList);
1180
+			}
1181
+		}
1182
+
1183
+		/**
1184
+		 * execute the actions to convert the html
1185
+		 *
1186
+		 * @access protected
1187
+		 */
1188
+		protected function _makeHTMLcode()
1189
+		{
1190
+			// foreach elements of the parsing
1191
+			for ($this->_parsePos=0; $this->_parsePos<count($this->parsingHtml->code); $this->_parsePos++) {
1192
+
1193
+				// get the action to do
1194
+				$action = $this->parsingHtml->code[$this->_parsePos];
1195
+
1196
+				// if it is a opening of table / ul / ol
1197
+				if (in_array($action['name'], array('table', 'ul', 'ol')) && !$action['close']) {
1198
+
1199
+					//  we will work as a sub HTML to calculate the size of the element
1200
+					$this->_subPart = true;
1201
+
1202
+					// get the name of the opening tag
1203
+					$tagOpen = $action['name'];
1204
+
1205
+					// save the actual pos on the parsing
1206
+					$this->_tempPos = $this->_parsePos;
1207
+
1208
+					// foreach elements, while we are in the opened tag
1209
+					while (isset($this->parsingHtml->code[$this->_tempPos]) && !($this->parsingHtml->code[$this->_tempPos]['name']==$tagOpen && $this->parsingHtml->code[$this->_tempPos]['close'])) {
1210
+						// make the action
1211
+						$this->_executeAction($this->parsingHtml->code[$this->_tempPos]);
1212
+						$this->_tempPos++;
1213
+					}
1214
+
1215
+					// execute the closure of the tag
1216
+					if (isset($this->parsingHtml->code[$this->_tempPos])) {
1217
+						$this->_executeAction($this->parsingHtml->code[$this->_tempPos]);
1218
+					}
1219
+
1220
+					// end of the sub part
1221
+					$this->_subPart = false;
1222
+				}
1223
+
1224
+				// execute the action
1225
+				$this->_executeAction($action);
1226
+			}
1227
+		}
1228
+
1229
+		/**
1230
+		 * execute the action from the parsing
1231
+		 *
1232
+		 * @access protected
1233
+		 * @param  array $action
1234
+		 */
1235
+		protected function _executeAction($action)
1236
+		{
1237
+			// name of the action
1238
+			$fnc = ($action['close'] ? '_tag_close_' : '_tag_open_').strtoupper($action['name']);
1239
+
1240
+			// parameters of the action
1241
+			$param = $action['param'];
1242
+
1243
+			// if it the first action of the first page, and if it is not a open tag of PAGE => create the new page
1244
+			if ($fnc!='_tag_open_PAGE' && $this->_firstPage) {
1245
+				$this->_setNewPage();
1246
+			}
1247
+
1248
+			// the action must exist
1249
+			if (!is_callable(array(&$this, $fnc))) {
1250
+				throw new HTML2PDF_exception(1, strtoupper($action['name']), $this->parsingHtml->getHtmlErrorCode($action['html_pos']));
1251
+			}
1252
+
1253
+			// lauch the action
1254
+			$res = $this->{$fnc}($param);
1255
+
1256
+			// save the name of the action
1257
+			$this->_previousCall = $fnc;
1258
+
1259
+			// return the result
1260
+			return $res;
1261
+		}
1262
+
1263
+		/**
1264
+		 * get the position of the element on the current line, depending on his height
1265
+		 *
1266
+		 * @access protected
1267
+		 * @param  float $h
1268
+		 * @return float
1269
+		 */
1270
+		protected function _getElementY($h)
1271
+		{
1272
+			if ($this->_subPart || $this->_isSubPart || !$this->_currentH || $this->_currentH<$h)
1273
+				return 0;
1274
+
1275
+			return ($this->_currentH-$h)*0.8;
1276
+		}
1277
+
1278
+		/**
1279
+		 * make a break line
1280
+		 *
1281
+		 * @access protected
1282
+		 * @param  float $h current line height
1283
+		 * @param  integer $curr real current position in the text, if new line in the write of a text
1284
+		 */
1285
+		protected function _makeBreakLine($h, $curr = null)
1286
+		{
1287
+			if ($h) {
1288
+				if (($this->pdf->getY()+$h<$this->pdf->getH() - $this->pdf->getbMargin()) || $this->_isInOverflow || $this->_isInFooter)
1289
+					$this->_setNewLine($h, $curr);
1290
+				else
1291
+					$this->_setNewPage(null, '', null, $curr);
1292
+			} else {
1293
+				$this->_setNewPositionForNewLine($curr);
1294
+			}
1295
+
1296
+			$this->_maxH = 0;
1297
+			$this->_maxE = 0;
1298
+		}
1299
+
1300
+		/**
1301
+		 * display a image
1302
+		 *
1303
+		 * @access protected
1304
+		 * @param  string $src
1305
+		 * @param  boolean $subLi if true=image of a list
1306
+		 * @return boolean depending on "isForOneLine"
1307
+		 */
1308
+		protected function _drawImage($src, $subLi=false)
1309
+		{
1310
+			// get the size of the image
1311
+			// WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
1312
+
1313
+			$infos=@getimagesize($src);
1314
+
1315
+			// if the image does not exist, or can not be loaded
1316
+			if (count($infos)<2) {
1317
+				// if the test is activ => exception
1318
+				if ($this->_testIsImage) {
1319
+					throw new HTML2PDF_exception(6, $src);
1320
+				}
1321
+
1322
+				// else, display a gray rectangle
1323
+				$src = null;
1324
+				$infos = array(16, 16);
1325
+			}
1326
+
1327
+			// convert the size of the image in the unit of the PDF
1328
+			$imageWidth = $infos[0]/$this->pdf->getK();
1329
+			$imageHeight = $infos[1]/$this->pdf->getK();
1330
+
1331
+			// calculate the size from the css style
1332
+			if ($this->parsingCss->value['width'] && $this->parsingCss->value['height']) {
1333
+				$w = $this->parsingCss->value['width'];
1334
+				$h = $this->parsingCss->value['height'];
1335
+			} else if ($this->parsingCss->value['width']) {
1336
+				$w = $this->parsingCss->value['width'];
1337
+				$h = $imageHeight*$w/$imageWidth;
1338
+			} else if ($this->parsingCss->value['height']) {
1339
+				$h = $this->parsingCss->value['height'];
1340
+				$w = $imageWidth*$h/$imageHeight;
1341
+			} else {
1342
+				// convert px to pt
1343
+				$w = 72./96.*$imageWidth;
1344
+				$h = 72./96.*$imageHeight;
1345
+			}
1346
+
1347
+			// are we in a float
1348
+			$float = $this->parsingCss->getFloat();
1349
+
1350
+			// if we are in a float, but if something else if on the line => Break Line
1351
+			if ($float && $this->_maxH) {
1352
+				// make the break line (false if we are in "_isForOneLine" mode)
1353
+				if (!$this->_tag_open_BR(array())) {
1354
+					return false;
1355
+				}
1356
+			}
1357
+
1358
+			// position of the image
1359
+			$x = $this->pdf->getX();
1360
+			$y = $this->pdf->getY();
1361
+
1362
+			// if the image can not be put on the current line => new line
1363
+			if (!$float && ($x + $w>$this->pdf->getW() - $this->pdf->getrMargin()) && $this->_maxH) {
1364
+				if ($this->_isForOneLine) {
1365
+					return false;
1366
+				}
1367
+
1368
+				// set the new line
1369
+				$hnl = max($this->_maxH, $this->parsingCss->getLineHeight());
1370
+				$this->_setNewLine($hnl);
1371
+
1372
+				// get the new position
1373
+				$x = $this->pdf->getX();
1374
+				$y = $this->pdf->getY();
1375
+			}
1376
+
1377
+			// if the image can not be put on the current page
1378
+			if (($y + $h>$this->pdf->getH() - $this->pdf->getbMargin()) && !$this->_isInOverflow) {
1379
+				// new page
1380
+				$this->_setNewPage();
1381
+
1382
+				// get the new position
1383
+				$x = $this->pdf->getX();
1384
+				$y = $this->pdf->getY();
1385
+			}
1386
+
1387
+			// correction for display the image of a list
1388
+			$hT = 0.80*$this->parsingCss->value['font-size'];
1389
+			if ($subLi && $h<$hT) {
1390
+				$y+=($hT-$h);
1391
+			}
1392
+
1393
+			// add the margin top
1394
+			$yc = $y-$this->parsingCss->value['margin']['t'];
1395
+
1396
+			// get the width and the position of the parent
1397
+			$old = $this->parsingCss->getOldValues();
1398
+			if ( $old['width']) {
1399
+				$parentWidth = $old['width'];
1400
+				$parentX = $x;
1401
+			} else {
1402
+				$parentWidth = $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
1403
+				$parentX = $this->pdf->getlMargin();
1404
+			}
1405
+
1406
+			// if we are in a gloat => adapt the parent position and width
1407
+			if ($float) {
1408
+				list($lx, $rx) = $this->_getMargins($yc);
1409
+				$parentX = $lx;
1410
+				$parentWidth = $rx-$lx;
1411
+			}
1412
+
1413
+			// calculate the position of the image, if align to the right
1414
+			if ($parentWidth>$w && $float!='left') {
1415
+				if ($float=='right' || $this->parsingCss->value['text-align']=='li_right')    $x = $parentX + $parentWidth - $w-$this->parsingCss->value['margin']['r']-$this->parsingCss->value['margin']['l'];
1416
+			}
1417
+
1418
+			// display the image
1419
+			if (!$this->_subPart && !$this->_isSubPart) {
1420
+				if ($src) {
1421
+					$this->pdf->Image($src, $x, $y, $w, $h, '', $this->_isInLink);
1422
+				} else {
1423
+					// rectangle if the image can not be loaded
1424
+					$this->pdf->setFillColorArray(array(240, 220, 220));
1425
+					$this->pdf->Rect($x, $y, $w, $h, 'F');
1426
+				}
1427
+			}
1428
+
1429
+			// apply the margins
1430
+			$x-= $this->parsingCss->value['margin']['l'];
1431
+			$y-= $this->parsingCss->value['margin']['t'];
1432
+			$w+= $this->parsingCss->value['margin']['l'] + $this->parsingCss->value['margin']['r'];
1433
+			$h+= $this->parsingCss->value['margin']['t'] + $this->parsingCss->value['margin']['b'];
1434
+
1435
+			if ($float=='left') {
1436
+				// save the current max
1437
+				$this->_maxX = max($this->_maxX, $x+$w);
1438
+				$this->_maxY = max($this->_maxY, $y+$h);
1439
+
1440
+				// add the image to the margins
1441
+				$this->_addMargins($float, $x, $y, $x+$w, $y+$h);
1442
+
1443
+				// get the new position
1444
+				list($lx, $rx) = $this->_getMargins($yc);
1445
+				$this->pdf->setXY($lx, $yc);
1446
+			} else if ($float=='right') {
1447
+				// save the current max. We don't save the X because it is not the real max of the line
1448
+				$this->_maxY = max($this->_maxY, $y+$h);
1449
+
1450
+				// add the image to the margins
1451
+				$this->_addMargins($float, $x, $y, $x+$w, $y+$h);
1452
+
1453
+				// get the new position
1454
+				list($lx, $rx) = $this->_getMargins($yc);
1455
+				$this->pdf->setXY($lx, $yc);
1456
+			} else {
1457
+				// set the new position at the end of the image
1458
+				$this->pdf->setX($x+$w);
1459
+
1460
+				// save the current max
1461
+				$this->_maxX = max($this->_maxX, $x+$w);
1462
+				$this->_maxY = max($this->_maxY, $y+$h);
1463
+				$this->_maxH = max($this->_maxH, $h);
1464
+			}
1465
+
1466
+			return true;
1467
+		}
1468
+
1469
+		/**
1470
+		 * draw a rectangle
1471
+		 *
1472
+		 * @access protected
1473
+		 * @param  float $x
1474
+		 * @param  float $y
1475
+		 * @param  float $w
1476
+		 * @param  float $h
1477
+		 * @param  array $border
1478
+		 * @param  float $padding - internal marge of the rectanble => not used, but...
1479
+		 * @param  float $margin  - external marge of the rectanble
1480
+		 * @param  array $background
1481
+		 * @return boolean
1482
+		 */
1483
+		protected function _drawRectangle($x, $y, $w, $h, $border, $padding, $margin, $background)
1484
+		{
1485
+			// if we are in a subpart or if height is null => return false
1486
+			if ($this->_subPart || $this->_isSubPart || $h===null) return false;
1487
+
1488
+			// add the margin
1489
+			$x+= $margin;
1490
+			$y+= $margin;
1491
+			$w-= $margin*2;
1492
+			$h-= $margin*2;
1493
+
1494
+			// get the radius of the border
1495
+			$outTL = $border['radius']['tl'];
1496
+			$outTR = $border['radius']['tr'];
1497
+			$outBR = $border['radius']['br'];
1498
+			$outBL = $border['radius']['bl'];
1499
+
1500
+			// prepare the out radius
1501
+			$outTL = ($outTL[0] && $outTL[1]) ? $outTL : null;
1502
+			$outTR = ($outTR[0] && $outTR[1]) ? $outTR : null;
1503
+			$outBR = ($outBR[0] && $outBR[1]) ? $outBR : null;
1504
+			$outBL = ($outBL[0] && $outBL[1]) ? $outBL : null;
1505
+
1506
+			// prepare the in radius
1507
+			$inTL = $outTL;
1508
+			$inTR = $outTR;
1509
+			$inBR = $outBR;
1510
+			$inBL = $outBL;
1511
+
1512
+			if (is_array($inTL)) {
1513
+				$inTL[0]-= $border['l']['width'];
1514
+				$inTL[1]-= $border['t']['width'];
1515
+			}
1516
+			if (is_array($inTR)) {
1517
+				$inTR[0]-= $border['r']['width'];
1518
+				$inTR[1]-= $border['t']['width'];
1519
+			}
1520
+			if (is_array($inBR)) {
1521
+				$inBR[0]-= $border['r']['width'];
1522
+				$inBR[1]-= $border['b']['width'];
1523
+			}
1524
+			if (is_array($inBL)) {
1525
+				$inBL[0]-= $border['l']['width'];
1526
+				$inBL[1]-= $border['b']['width'];
1527
+			}
1528
+
1529
+			if ($inTL[0]<=0 || $inTL[1]<=0) $inTL = null;
1530
+			if ($inTR[0]<=0 || $inTR[1]<=0) $inTR = null;
1531
+			if ($inBR[0]<=0 || $inBR[1]<=0) $inBR = null;
1532
+			if ($inBL[0]<=0 || $inBL[1]<=0) $inBL = null;
1533
+
1534
+			// prepare the background color
1535
+			$pdfStyle = '';
1536
+			if ($background['color']) {
1537
+				$this->pdf->setFillColorArray($background['color']);
1538
+				$pdfStyle.= 'F';
1539
+			}
1540
+
1541
+			// if we have a background to fill => fill it with a path (because of the radius)
1542
+			if ($pdfStyle) {
1543
+				$this->pdf->clippingPathStart($x, $y, $w, $h, $outTL, $outTR, $outBL, $outBR);
1544
+				$this->pdf->Rect($x, $y, $w, $h, $pdfStyle);
1545
+				$this->pdf->clippingPathStop();
1546
+			}
1547
+
1548
+			// prepare the background image
1549
+			if ($background['image']) {
1550
+				$iName      = $background['image'];
1551
+				$iPosition  = $background['position']!==null ? $background['position'] : array(0, 0);
1552
+				$iRepeat    = $background['repeat']!==null   ? $background['repeat']   : array(true, true);
1553
+
1554
+				// size of the background without the borders
1555
+				$bX = $x;
1556
+				$bY = $y;
1557
+				$bW = $w;
1558
+				$bH = $h;
1559
+
1560
+				if ($border['b']['width']) {
1561
+					$bH-= $border['b']['width'];
1562
+				}
1563
+				if ($border['l']['width']) {
1564
+					$bW-= $border['l']['width'];
1565
+					$bX+= $border['l']['width'];
1566
+				}
1567
+				if ($border['t']['width']) {
1568
+					$bH-= $border['t']['width'];
1569
+					$bY+= $border['t']['width'];
1570
+				}
1571
+				if ($border['r']['width']) {
1572
+					$bW-= $border['r']['width'];
1573
+				}
1574
+
1575
+				// get the size of the image
1576
+				// WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
1577
+				$imageInfos=@getimagesize($iName);
1578
+
1579
+				// if the image can not be loaded
1580
+				if (count($imageInfos)<2) {
1581
+					if ($this->_testIsImage) {
1582
+						throw new HTML2PDF_exception(6, $iName);
1583
+					}
1584
+				} else {
1585
+					// convert the size of the image from pixel to the unit of the PDF
1586
+					$imageWidth    = 72./96.*$imageInfos[0]/$this->pdf->getK();
1587
+					$imageHeight    = 72./96.*$imageInfos[1]/$this->pdf->getK();
1588
+
1589
+					// prepare the position of the backgroung
1590
+					if ($iRepeat[0]) $iPosition[0] = $bX;
1591
+					else if (preg_match('/^([-]?[0-9\.]+)%/isU', $iPosition[0], $match)) $iPosition[0] = $bX + $match[1]*($bW-$imageWidth)/100;
1592
+					else $iPosition[0] = $bX+$iPosition[0];
1593
+
1594
+					if ($iRepeat[1]) $iPosition[1] = $bY;
1595
+					else if (preg_match('/^([-]?[0-9\.]+)%/isU', $iPosition[1], $match)) $iPosition[1] = $bY + $match[1]*($bH-$imageHeight)/100;
1596
+					else $iPosition[1] = $bY+$iPosition[1];
1597
+
1598
+					$imageXmin = $bX;
1599
+					$imageXmax = $bX+$bW;
1600
+					$imageYmin = $bY;
1601
+					$imageYmax = $bY+$bH;
1602
+
1603
+					if (!$iRepeat[0] && !$iRepeat[1]) {
1604
+						$imageXmin =     $iPosition[0]; $imageXmax =     $iPosition[0]+$imageWidth;
1605
+						$imageYmin =     $iPosition[1]; $imageYmax =     $iPosition[1]+$imageHeight;
1606
+					} else if ($iRepeat[0] && !$iRepeat[1]) {
1607
+						$imageYmin =     $iPosition[1]; $imageYmax =     $iPosition[1]+$imageHeight;
1608
+					} else if (!$iRepeat[0] && $iRepeat[1]) {
1609
+						$imageXmin =     $iPosition[0]; $imageXmax =     $iPosition[0]+$imageWidth;
1610
+					}
1611
+
1612
+					// build the path to display the image (because of radius)
1613
+					$this->pdf->clippingPathStart($bX, $bY, $bW, $bH, $inTL, $inTR, $inBL, $inBR);
1614
+
1615
+					// repeat the image
1616
+					for ($iY=$imageYmin; $iY<$imageYmax; $iY+=$imageHeight) {
1617
+						for ($iX=$imageXmin; $iX<$imageXmax; $iX+=$imageWidth) {
1618
+							$cX = null;
1619
+							$cY = null;
1620
+							$cW = $imageWidth;
1621
+							$cH = $imageHeight;
1622
+							if ($imageYmax-$iY<$imageHeight) {
1623
+								$cX = $iX;
1624
+								$cY = $iY;
1625
+								$cH = $imageYmax-$iY;
1626
+							}
1627
+							if ($imageXmax-$iX<$imageWidth) {
1628
+								$cX = $iX;
1629
+								$cY = $iY;
1630
+								$cW = $imageXmax-$iX;
1631
+							}
1632
+
1633
+							$this->pdf->Image($iName, $iX, $iY, $imageWidth, $imageHeight, '', '');
1634
+						}
1635
+					}
1636
+
1637
+					// end of the path
1638
+					$this->pdf->clippingPathStop();
1639
+				}
1640
+			}
1641
+
1642
+			// adding some loose (0.01mm)
1643
+			$loose = 0.01;
1644
+			$x-= $loose;
1645
+			$y-= $loose;
1646
+			$w+= 2.*$loose;
1647
+			$h+= 2.*$loose;
1648
+			if ($border['l']['width']) $border['l']['width']+= 2.*$loose;
1649
+			if ($border['t']['width']) $border['t']['width']+= 2.*$loose;
1650
+			if ($border['r']['width']) $border['r']['width']+= 2.*$loose;
1651
+			if ($border['b']['width']) $border['b']['width']+= 2.*$loose;
1652
+
1653
+			// prepare the test on borders
1654
+			$testBl = ($border['l']['width'] && $border['l']['color'][0]!==null);
1655
+			$testBt = ($border['t']['width'] && $border['t']['color'][0]!==null);
1656
+			$testBr = ($border['r']['width'] && $border['r']['color'][0]!==null);
1657
+			$testBb = ($border['b']['width'] && $border['b']['color'][0]!==null);
1658
+
1659
+			// draw the radius bottom-left
1660
+			if (is_array($outBL) && ($testBb || $testBl)) {
1661
+				if ($inBL) {
1662
+					$courbe = array();
1663
+					$courbe[] = $x+$outBL[0];              $courbe[] = $y+$h;
1664
+					$courbe[] = $x;                        $courbe[] = $y+$h-$outBL[1];
1665
+					$courbe[] = $x+$outBL[0];              $courbe[] = $y+$h-$border['b']['width'];
1666
+					$courbe[] = $x+$border['l']['width'];  $courbe[] = $y+$h-$outBL[1];
1667
+					$courbe[] = $x+$outBL[0];              $courbe[] = $y+$h-$outBL[1];
1668
+				} else {
1669
+					$courbe = array();
1670
+					$courbe[] = $x+$outBL[0];              $courbe[] = $y+$h;
1671
+					$courbe[] = $x;                        $courbe[] = $y+$h-$outBL[1];
1672
+					$courbe[] = $x+$border['l']['width'];  $courbe[] = $y+$h-$border['b']['width'];
1673
+					$courbe[] = $x+$outBL[0];              $courbe[] = $y+$h-$outBL[1];
1674
+				}
1675
+				$this->_drawCurve($courbe, $border['l']['color']);
1676
+			}
1677
+
1678
+			// draw the radius left-top
1679
+			if (is_array($outTL) && ($testBt || $testBl)) {
1680
+				if ($inTL) {
1681
+					$courbe = array();
1682
+					$courbe[] = $x;                        $courbe[] = $y+$outTL[1];
1683
+					$courbe[] = $x+$outTL[0];              $courbe[] = $y;
1684
+					$courbe[] = $x+$border['l']['width'];  $courbe[] = $y+$outTL[1];
1685
+					$courbe[] = $x+$outTL[0];              $courbe[] = $y+$border['t']['width'];
1686
+					$courbe[] = $x+$outTL[0];              $courbe[] = $y+$outTL[1];
1687
+				} else {
1688
+					$courbe = array();
1689
+					$courbe[] = $x;                        $courbe[] = $y+$outTL[1];
1690
+					$courbe[] = $x+$outTL[0];              $courbe[] = $y;
1691
+					$courbe[] = $x+$border['l']['width'];  $courbe[] = $y+$border['t']['width'];
1692
+					$courbe[] = $x+$outTL[0];              $courbe[] = $y+$outTL[1];
1693
+				}
1694
+				$this->_drawCurve($courbe, $border['t']['color']);
1695
+			}
1696
+
1697
+			// draw the radius top-right
1698
+			if (is_array($outTR) && ($testBt || $testBr)) {
1699
+				if ($inTR) {
1700
+					$courbe = array();
1701
+					$courbe[] = $x+$w-$outTR[0];             $courbe[] = $y;
1702
+					$courbe[] = $x+$w;                       $courbe[] = $y+$outTR[1];
1703
+					$courbe[] = $x+$w-$outTR[0];             $courbe[] = $y+$border['t']['width'];
1704
+					$courbe[] = $x+$w-$border['r']['width']; $courbe[] = $y+$outTR[1];
1705
+					$courbe[] = $x+$w-$outTR[0];             $courbe[] = $y+$outTR[1];
1706
+				} else {
1707
+					$courbe = array();
1708
+					$courbe[] = $x+$w-$outTR[0];             $courbe[] = $y;
1709
+					$courbe[] = $x+$w;                       $courbe[] = $y+$outTR[1];
1710
+					$courbe[] = $x+$w-$border['r']['width']; $courbe[] = $y+$border['t']['width'];
1711
+					$courbe[] = $x+$w-$outTR[0];             $courbe[] = $y+$outTR[1];
1712
+				}
1713
+				$this->_drawCurve($courbe, $border['r']['color']);
1714
+			}
1715
+
1716
+			// draw the radius right-bottom
1717
+			if (is_array($outBR) && ($testBb || $testBr)) {
1718
+				if ($inBR) {
1719
+					$courbe = array();
1720
+					$courbe[] = $x+$w;                       $courbe[] = $y+$h-$outBR[1];
1721
+					$courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h;
1722
+					$courbe[] = $x+$w-$border['r']['width']; $courbe[] = $y+$h-$outBR[1];
1723
+					$courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h-$border['b']['width'];
1724
+					$courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h-$outBR[1];
1725
+				} else {
1726
+					$courbe = array();
1727
+					$courbe[] = $x+$w;                       $courbe[] = $y+$h-$outBR[1];
1728
+					$courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h;
1729
+					$courbe[] = $x+$w-$border['r']['width']; $courbe[] = $y+$h-$border['b']['width'];
1730
+					$courbe[] = $x+$w-$outBR[0];             $courbe[] = $y+$h-$outBR[1];
1731
+				}
1732
+				$this->_drawCurve($courbe, $border['b']['color']);
1733
+			}
1734
+
1735
+			// draw the left border
1736
+			if ($testBl) {
1737
+				$pt = array();
1738
+				$pt[] = $x;                       $pt[] = $y+$h;
1739
+				$pt[] = $x;                       $pt[] = $y+$h-$border['b']['width'];
1740
+				$pt[] = $x;                       $pt[] = $y+$border['t']['width'];
1741
+				$pt[] = $x;                       $pt[] = $y;
1742
+				$pt[] = $x+$border['l']['width']; $pt[] = $y+$border['t']['width'];
1743
+				$pt[] = $x+$border['l']['width']; $pt[] = $y+$h-$border['b']['width'];
1744
+
1745
+				$bord = 3;
1746
+				if (is_array($outBL)) {
1747
+					$bord-=1;
1748
+					$pt[3] -= $outBL[1] - $border['b']['width'];
1749
+					if ($inBL) $pt[11]-= $inBL[1];
1750
+					unset($pt[0]);unset($pt[1]);
1751
+				}
1752
+				if (is_array($outTL)) {
1753
+					$bord-=2;
1754
+					$pt[5] += $outTL[1]-$border['t']['width'];
1755
+					if ($inTL) $pt[9] += $inTL[1];
1756
+					unset($pt[6]);unset($pt[7]);
1757
+				}
1758
+
1759
+				$pt = array_values($pt);
1760
+				$this->_drawLine($pt, $border['l']['color'], $border['l']['type'], $border['l']['width'], $bord);
1761
+			}
1762
+
1763
+			// draw the top border
1764
+			if ($testBt) {
1765
+				$pt = array();
1766
+				$pt[] = $x;                          $pt[] = $y;
1767
+				$pt[] = $x+$border['l']['width'];    $pt[] = $y;
1768
+				$pt[] = $x+$w-$border['r']['width']; $pt[] = $y;
1769
+				$pt[] = $x+$w;                       $pt[] = $y;
1770
+				$pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$border['t']['width'];
1771
+				$pt[] = $x+$border['l']['width'];    $pt[] = $y+$border['t']['width'];
1772
+
1773
+				$bord = 3;
1774
+				if (is_array($outTL)) {
1775
+					$bord-=1;
1776
+					$pt[2] += $outTL[0] - $border['l']['width'];
1777
+					if ($inTL) $pt[10]+= $inTL[0];
1778
+					unset($pt[0]);unset($pt[1]);
1779
+				}
1780
+				if (is_array($outTR)) {
1781
+					$bord-=2;
1782
+					$pt[4] -= $outTR[0] - $border['r']['width'];
1783
+					if ($inTR) $pt[8] -= $inTR[0];
1784
+					unset($pt[6]);unset($pt[7]);
1785
+				}
1786
+
1787
+				$pt = array_values($pt);
1788
+				$this->_drawLine($pt, $border['t']['color'], $border['t']['type'], $border['t']['width'], $bord);
1789
+			}
1790
+
1791
+			// draw the right border
1792
+			if ($testBr) {
1793
+				$pt = array();
1794
+				$pt[] = $x+$w;                       $pt[] = $y;
1795
+				$pt[] = $x+$w;                       $pt[] = $y+$border['t']['width'];
1796
+				$pt[] = $x+$w;                       $pt[] = $y+$h-$border['b']['width'];
1797
+				$pt[] = $x+$w;                       $pt[] = $y+$h;
1798
+				$pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$h-$border['b']['width'];
1799
+				$pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$border['t']['width'];
1800
+
1801
+				$bord = 3;
1802
+				if (is_array($outTR)) {
1803
+					$bord-=1;
1804
+					$pt[3] += $outTR[1] - $border['t']['width'];
1805
+					if ($inTR) $pt[11]+= $inTR[1];
1806
+					unset($pt[0]);unset($pt[1]);
1807
+				}
1808
+				if (is_array($outBR)) {
1809
+					$bord-=2;
1810
+					$pt[5] -= $outBR[1] - $border['b']['width'];
1811
+					if ($inBR) $pt[9] -= $inBR[1];
1812
+					unset($pt[6]);unset($pt[7]);
1813
+				}
1814
+
1815
+				$pt = array_values($pt);
1816
+				$this->_drawLine($pt, $border['r']['color'], $border['r']['type'], $border['r']['width'], $bord);
1817
+			}
1818
+
1819
+			// draw the bottom border
1820
+			if ($testBb) {
1821
+				$pt = array();
1822
+				$pt[] = $x+$w;                       $pt[] = $y+$h;
1823
+				$pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$h;
1824
+				$pt[] = $x+$border['l']['width'];    $pt[] = $y+$h;
1825
+				$pt[] = $x;                          $pt[] = $y+$h;
1826
+				$pt[] = $x+$border['l']['width'];    $pt[] = $y+$h-$border['b']['width'];
1827
+				$pt[] = $x+$w-$border['r']['width']; $pt[] = $y+$h-$border['b']['width'];
1828
+
1829
+				$bord = 3;
1830
+				if (is_array($outBL)) {
1831
+					$bord-=2;
1832
+					$pt[4] += $outBL[0] - $border['l']['width'];
1833
+					if ($inBL) $pt[8] += $inBL[0];
1834
+					unset($pt[6]);unset($pt[7]);
1835
+				}
1836
+				if (is_array($outBR)) {
1837
+					$bord-=1;
1838
+					$pt[2] -= $outBR[0] - $border['r']['width'];
1839
+					if ($inBR) $pt[10]-= $inBR[0];
1840
+					unset($pt[0]);unset($pt[1]);
1841
+
1842
+				}
1843
+
1844
+				$pt = array_values($pt);
1845
+				$this->_drawLine($pt, $border['b']['color'], $border['b']['type'], $border['b']['width'], $bord);
1846
+			}
1847
+
1848
+			if ($background['color']) {
1849
+				$this->pdf->setFillColorArray($background['color']);
1850
+			}
1851
+
1852
+			return true;
1853
+		}
1854
+
1855
+		/**
1856
+		 * draw a curve (for border radius)
1857
+		 *
1858
+		 * @access protected
1859
+		 * @param  array $pt
1860
+		 * @param  array $color
1861
+		 */
1862
+		protected function _drawCurve($pt, $color)
1863
+		{
1864
+			$this->pdf->setFillColorArray($color);
1865
+
1866
+			if (count($pt)==10)
1867
+				$this->pdf->drawCurve($pt[0], $pt[1], $pt[2], $pt[3], $pt[4], $pt[5], $pt[6], $pt[7], $pt[8], $pt[9]);
1868
+			else
1869
+				$this->pdf->drawCorner($pt[0], $pt[1], $pt[2], $pt[3], $pt[4], $pt[5], $pt[6], $pt[7]);
1870
+		}
1871
+
1872
+		/**
1873
+		 * draw a ligne with a specific type, and specific start and end for radius
1874
+		 *
1875
+		 * @access protected
1876
+		 * @param  array   $pt
1877
+		 * @param  float   $color
1878
+		 * @param  string  $type (dashed, dotted, double, solid)
1879
+		 * @param  float   $width
1880
+		 * @param  integer $radius (binary from 0 to 3 with 1=>start with a radius, 2=>end with a radius)
1881
+		 */
1882
+		protected function _drawLine($pt, $color, $type, $width, $radius=3)
1883
+		{
1884
+			// set the fill color
1885
+			$this->pdf->setFillColorArray($color);
1886
+
1887
+			// if dashed or dotted
1888
+			if ($type=='dashed' || $type=='dotted') {
1889
+
1890
+				// clean the end of the line, if radius
1891
+				if ($radius==1) {
1892
+					$tmp = array(); $tmp[]=$pt[0]; $tmp[]=$pt[1]; $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[8]; $tmp[]=$pt[9];
1893
+					$this->pdf->Polygon($tmp, 'F');
1894
+
1895
+					$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];
1896
+					$pt = $tmp;
1897
+				} else if ($radius==2) {
1898
+					$tmp = array(); $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[4]; $tmp[]=$pt[5]; $tmp[]=$pt[6]; $tmp[]=$pt[7];
1899
+					$this->pdf->Polygon($tmp, 'F');
1900
+
1901
+					$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];
1902
+					$pt = $tmp;
1903
+				} else if ($radius==3) {
1904
+					$tmp = array(); $tmp[]=$pt[0]; $tmp[]=$pt[1]; $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[10]; $tmp[]=$pt[11];
1905
+					$this->pdf->Polygon($tmp, 'F');
1906
+
1907
+					$tmp = array(); $tmp[]=$pt[4]; $tmp[]=$pt[5]; $tmp[]=$pt[6]; $tmp[]=$pt[7]; $tmp[]=$pt[8]; $tmp[]=$pt[9];
1908
+					$this->pdf->Polygon($tmp, 'F');
1909
+
1910
+					$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];
1911
+					$pt = $tmp;
1912
+				}
1913
+
1914
+				// horisontal or vertical line
1915
+				if ($pt[2]==$pt[0]) {
1916
+					$l = abs(($pt[3]-$pt[1])*0.5);
1917
+					$px = 0;
1918
+					$py = $width;
1919
+					$x1 = $pt[0]; $y1 = ($pt[3]+$pt[1])*0.5;
1920
+					$x2 = $pt[6]; $y2 = ($pt[7]+$pt[5])*0.5;
1921
+				} else {
1922
+					$l = abs(($pt[2]-$pt[0])*0.5);
1923
+					$px = $width;
1924
+					$py = 0;
1925
+					$x1 = ($pt[2]+$pt[0])*0.5; $y1 = $pt[1];
1926
+					$x2 = ($pt[6]+$pt[4])*0.5; $y2 = $pt[7];
1927
+				}
1928
+
1929
+				// if dashed : 3x bigger than dotted
1930
+				if ($type=='dashed') {
1931
+					$px = $px*3.;
1932
+					$py = $py*3.;
1933
+				}
1934
+				$mode = ($l/($px+$py)<.5);
1935
+
1936
+				// display the dotted/dashed line
1937
+				for ($i=0; $l-($px+$py)*($i-0.5)>0; $i++) {
1938
+					if (($i%2)==$mode) {
1939
+						$j = $i-0.5;
1940
+						$lx1 = $px*($j);   if ($lx1<-$l) $lx1 =-$l;
1941
+						$ly1 = $py*($j);   if ($ly1<-$l) $ly1 =-$l;
1942
+						$lx2 = $px*($j+1); if ($lx2>$l)  $lx2 = $l;
1943
+						$ly2 = $py*($j+1); if ($ly2>$l)  $ly2 = $l;
1944
+
1945
+						$tmp = array();
1946
+						$tmp[] = $x1+$lx1; $tmp[] = $y1+$ly1;
1947
+						$tmp[] = $x1+$lx2; $tmp[] = $y1+$ly2;
1948
+						$tmp[] = $x2+$lx2; $tmp[] = $y2+$ly2;
1949
+						$tmp[] = $x2+$lx1; $tmp[] = $y2+$ly1;
1950
+						$this->pdf->Polygon($tmp, 'F');
1951
+
1952
+						if ($j>0) {
1953
+							$tmp = array();
1954
+							$tmp[] = $x1-$lx1; $tmp[] = $y1-$ly1;
1955
+							$tmp[] = $x1-$lx2; $tmp[] = $y1-$ly2;
1956
+							$tmp[] = $x2-$lx2; $tmp[] = $y2-$ly2;
1957
+							$tmp[] = $x2-$lx1; $tmp[] = $y2-$ly1;
1958
+							$this->pdf->Polygon($tmp, 'F');
1959
+						}
1960
+					}
1961
+				}
1962
+			} else if ($type=='double') {
1963
+
1964
+				// if double, 2 lines : 0=>1/3 and 2/3=>1
1965
+				$pt1 = $pt;
1966
+				$pt2 = $pt;
1967
+
1968
+				if (count($pt)==12) {
1969
+					// line 1
1970
+					$pt1[0] = ($pt[0]-$pt[10])*0.33 + $pt[10];
1971
+					$pt1[1] = ($pt[1]-$pt[11])*0.33 + $pt[11];
1972
+					$pt1[2] = ($pt[2]-$pt[10])*0.33 + $pt[10];
1973
+					$pt1[3] = ($pt[3]-$pt[11])*0.33 + $pt[11];
1974
+					$pt1[4] = ($pt[4]-$pt[8])*0.33 + $pt[8];
1975
+					$pt1[5] = ($pt[5]-$pt[9])*0.33 + $pt[9];
1976
+					$pt1[6] = ($pt[6]-$pt[8])*0.33 + $pt[8];
1977
+					$pt1[7] = ($pt[7]-$pt[9])*0.33 + $pt[9];
1978
+					$pt2[10]= ($pt[10]-$pt[0])*0.33 + $pt[0];
1979
+					$pt2[11]= ($pt[11]-$pt[1])*0.33 + $pt[1];
1980
+
1981
+					// line 2
1982
+					$pt2[2] = ($pt[2] -$pt[0])*0.33 + $pt[0];
1983
+					$pt2[3] = ($pt[3] -$pt[1])*0.33 + $pt[1];
1984
+					$pt2[4] = ($pt[4] -$pt[6])*0.33 + $pt[6];
1985
+					$pt2[5] = ($pt[5] -$pt[7])*0.33 + $pt[7];
1986
+					$pt2[8] = ($pt[8] -$pt[6])*0.33 + $pt[6];
1987
+					$pt2[9] = ($pt[9] -$pt[7])*0.33 + $pt[7];
1988
+				} else {
1989
+					// line 1
1990
+					$pt1[0] = ($pt[0]-$pt[6])*0.33 + $pt[6];
1991
+					$pt1[1] = ($pt[1]-$pt[7])*0.33 + $pt[7];
1992
+					$pt1[2] = ($pt[2]-$pt[4])*0.33 + $pt[4];
1993
+					$pt1[3] = ($pt[3]-$pt[5])*0.33 + $pt[5];
1994
+
1995
+					// line 2
1996
+					$pt2[6] = ($pt[6]-$pt[0])*0.33 + $pt[0];
1997
+					$pt2[7] = ($pt[7]-$pt[1])*0.33 + $pt[1];
1998
+					$pt2[4] = ($pt[4]-$pt[2])*0.33 + $pt[2];
1999
+					$pt2[5] = ($pt[5]-$pt[3])*0.33 + $pt[3];
2000
+				}
2001
+				$this->pdf->Polygon($pt1, 'F');
2002
+				$this->pdf->Polygon($pt2, 'F');
2003
+			} else if ($type=='solid') {
2004
+				// solid line : draw directly the polygon
2005
+				$this->pdf->Polygon($pt, 'F');
2006
+			}
2007
+		}
2008
+
2009
+		/**
2010
+		 * prepare a transform matrix, only for drawing a SVG graphic
2011
+		 *
2012
+		 * @access protected
2013
+		 * @param  string $transform
2014
+		 * @return array  $matrix
2015
+		 */
2016
+		protected function _prepareTransform($transform)
2017
+		{
2018
+			// it can not be  empty
2019
+			if (!$transform) return null;
2020
+
2021
+			// sctions must be like scale(...)
2022
+			if (!preg_match_all('/([a-z]+)\(([^\)]*)\)/isU', $transform, $match)) return null;
2023
+
2024
+			// prepare the list of the actions
2025
+			$actions = array();
2026
+
2027
+			// for actions
2028
+			for ($k=0; $k<count($match[0]); $k++) {
2029
+
2030
+				// get the name of the action
2031
+				$name = strtolower($match[1][$k]);
2032
+
2033
+				// get the parameters of the action
2034
+				$val = explode(',', trim($match[2][$k]));
2035
+				foreach ($val as $i => $j) {
2036
+					$val[$i] = trim($j);
2037
+				}
2038
+
2039
+				// prepare the matrix, depending on the action
2040
+				switch($name)
2041
+				{
2042
+					case 'scale':
2043
+						if (!isset($val[0])) $val[0] = 1.;      else $val[0] = 1.*$val[0];
2044
+						if (!isset($val[1])) $val[1] = $val[0]; else $val[1] = 1.*$val[1];
2045
+						$actions[] = array($val[0],0,0,$val[1],0,0);
2046
+						break;
2047
+
2048
+					case 'translate':
2049
+						if (!isset($val[0])) $val[0] = 0.; else $val[0] = $this->parsingCss->ConvertToMM($val[0], $this->_isInDraw['w']);
2050
+						if (!isset($val[1])) $val[1] = 0.; else $val[1] = $this->parsingCss->ConvertToMM($val[1], $this->_isInDraw['h']);
2051
+						$actions[] = array(1,0,0,1,$val[0],$val[1]);
2052
+						break;
2053
+
2054
+					case 'rotate':
2055
+						if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*M_PI/180.;
2056
+						if (!isset($val[1])) $val[1] = 0.; else $val[1] = $this->parsingCss->ConvertToMM($val[1], $this->_isInDraw['w']);
2057
+						if (!isset($val[2])) $val[2] = 0.; else $val[2] = $this->parsingCss->ConvertToMM($val[2], $this->_isInDraw['h']);
2058
+						if ($val[1] || $val[2]) $actions[] = array(1,0,0,1,-$val[1],-$val[2]);
2059
+						$actions[] = array(cos($val[0]),sin($val[0]),-sin($val[0]),cos($val[0]),0,0);
2060
+						if ($val[1] || $val[2]) $actions[] = array(1,0,0,1,$val[1],$val[2]);
2061
+						break;
2062
+
2063
+					case 'skewx':
2064
+						if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*M_PI/180.;
2065
+						$actions[] = array(1,0,tan($val[0]),1,0,0);
2066
+						break;
2067
+
2068
+					case 'skewy':
2069
+						if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*M_PI/180.;
2070
+						$actions[] = array(1,tan($val[0]),0,1,0,0);
2071
+						break;
2072
+					case 'matrix':
2073
+						if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*1.;
2074
+						if (!isset($val[1])) $val[1] = 0.; else $val[1] = $val[1]*1.;
2075
+						if (!isset($val[2])) $val[2] = 0.; else $val[2] = $val[2]*1.;
2076
+						if (!isset($val[3])) $val[3] = 0.; else $val[3] = $val[3]*1.;
2077
+						if (!isset($val[4])) $val[4] = 0.; else $val[4] = $this->parsingCss->ConvertToMM($val[4], $this->_isInDraw['w']);
2078
+						if (!isset($val[5])) $val[5] = 0.; else $val[5] = $this->parsingCss->ConvertToMM($val[5], $this->_isInDraw['h']);
2079
+						$actions[] =$val;
2080
+						break;
2081
+				}
2082
+			}
2083
+
2084
+			// if ther is no actions => return
2085
+			if (!$actions) return null;
2086
+
2087
+			// get the first matrix
2088
+			$m = $actions[0]; unset($actions[0]);
2089
+
2090
+			// foreach matrix => multiply to the last matrix
2091
+			foreach ($actions as $n) {
2092
+				$m = array(
2093
+					$m[0]*$n[0]+$m[2]*$n[1],
2094
+					$m[1]*$n[0]+$m[3]*$n[1],
2095
+					$m[0]*$n[2]+$m[2]*$n[3],
2096
+					$m[1]*$n[2]+$m[3]*$n[3],
2097
+					$m[0]*$n[4]+$m[2]*$n[5]+$m[4],
2098
+					$m[1]*$n[4]+$m[3]*$n[5]+$m[5]
2099
+				);
2100
+			}
2101
+
2102
+			// return the matrix
2103
+			return $m;
2104
+		}
2105
+
2106
+		/**
2107
+		 * @access protected
2108
+		 * @param  &array $cases
2109
+		 * @param  &array $corr
2110
+		 */
2111
+		protected function _calculateTableCellSize(&$cases, &$corr)
2112
+		{
2113
+			if (!isset($corr[0])) return true;
2114
+
2115
+			// for each cell without colspan, we get the max width for each column
2116
+			$sw = array();
2117
+			for ($x=0; $x<count($corr[0]); $x++) {
2118
+				$m=0;
2119
+				for ($y=0; $y<count($corr); $y++) {
2120
+					if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][2]==1) {
2121
+						$m = max($m, $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w']);
2122
+					}
2123
+				}
2124
+				$sw[$x] = $m;
2125
+			}
2126
+
2127
+			// for each cell with colspan, we adapt the width of each column
2128
+			for ($x=0; $x<count($corr[0]); $x++) {
2129
+				for ($y=0; $y<count($corr); $y++) {
2130
+					if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][2]>1) {
2131
+
2132
+						// sum the max width of each column in colspan
2133
+						$s = 0; for ($i=0; $i<$corr[$y][$x][2]; $i++) $s+= $sw[$x+$i];
2134
+
2135
+						// if the max width is < the width of the cell with colspan => we adapt the width of each max width
2136
+						if ($s>0 && $s<$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w']) {
2137
+							for ($i=0; $i<$corr[$y][$x][2]; $i++) {
2138
+								$sw[$x+$i] = $sw[$x+$i]/$s*$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'];
2139
+							}
2140
+						}
2141
+					}
2142
+				}
2143
+			}
2144
+
2145
+			// set the new width, for each cell
2146
+			for ($x=0; $x<count($corr[0]); $x++) {
2147
+				for ($y=0; $y<count($corr); $y++) {
2148
+					if (isset($corr[$y][$x]) && is_array($corr[$y][$x])) {
2149
+						// without colspan
2150
+						if ($corr[$y][$x][2]==1) {
2151
+							$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'] = $sw[$x];
2152
+						// with colspan
2153
+						} else {
2154
+							$s = 0;
2155
+							for ($i=0; $i<$corr[$y][$x][2]; $i++) {
2156
+								$s+= $sw[$x+$i];
2157
+							}
2158
+							$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'] = $s;
2159
+						}
2160
+					}
2161
+				}
2162
+			}
2163
+
2164
+			// for each cell without rowspan, we get the max height for each line
2165
+			$sh = array();
2166
+			for ($y=0; $y<count($corr); $y++) {
2167
+				$m=0;
2168
+				for ($x=0; $x<count($corr[0]); $x++) {
2169
+					if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][3]==1) {
2170
+						$m = max($m, $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h']);
2171
+					}
2172
+				}
2173
+				$sh[$y] = $m;
2174
+			}
2175
+
2176
+			// for each cell with rowspan, we adapt the height of each line
2177
+			for ($y=0; $y<count($corr); $y++) {
2178
+				for ($x=0; $x<count($corr[0]); $x++) {
2179
+					if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][3]>1) {
2180
+
2181
+						// sum the max height of each line in rowspan
2182
+						$s = 0; for ($i=0; $i<$corr[$y][$x][3]; $i++) $s+= $sh[$y+$i];
2183
+
2184
+						// if the max height is < the height of the cell with rowspan => we adapt the height of each max height
2185
+						if ($s>0 && $s<$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h']) {
2186
+							for ($i=0; $i<$corr[$y][$x][3]; $i++) {
2187
+								$sh[$y+$i] = $sh[$y+$i]/$s*$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h'];
2188
+							}
2189
+						}
2190
+					}
2191
+				}
2192
+			}
2193
+
2194
+			// set the new height, for each cell
2195
+			for ($y=0; $y<count($corr); $y++) {
2196
+				for ($x=0; $x<count($corr[0]); $x++) {
2197
+					if (isset($corr[$y][$x]) && is_array($corr[$y][$x])) {
2198
+						// without rowspan
2199
+						if ($corr[$y][$x][3]==1) {
2200
+							$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h'] = $sh[$y];
2201
+						// with rowspan
2202
+						} else {
2203
+							$s = 0;
2204
+							for ($i=0; $i<$corr[$y][$x][3]; $i++) {
2205
+								$s+= $sh[$y+$i];
2206
+							}
2207
+							$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h'] = $s;
2208
+
2209
+							for ($j=1; $j<$corr[$y][$x][3]; $j++) {
2210
+								$tx = $x+1;
2211
+								$ty = $y+$j;
2212
+								for (true; isset($corr[$ty][$tx]) && !is_array($corr[$ty][$tx]); $tx++);
2213
+								if (isset($corr[$ty][$tx])) {
2214
+									$cases[$corr[$ty][$tx][1]][$corr[$ty][$tx][0]]['dw']+= $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'];
2215
+								}
2216
+							}
2217
+						}
2218
+					}
2219
+				}
2220
+			}
2221
+		}
2222
+
2223
+		/**
2224
+		 * tag : PAGE
2225
+		 * mode : OPEN
2226
+		 *
2227
+		 * @param  array $param
2228
+		 * @return boolean
2229
+		 */
2230
+		protected function _tag_open_PAGE($param)
2231
+		{
2232
+			if ($this->_isForOneLine) return false;
2233
+			if ($this->_debugActif) $this->_DEBUG_add('PAGE '.($this->_page+1), true);
2234
+
2235
+			$newPageSet= (!isset($param['pageset']) || $param['pageset']!='old');
2236
+
2237
+			$resetPageNumber = (isset($param['pagegroup']) && $param['pagegroup']=='new');
2238
+
2239
+			$this->_maxH = 0;
2240
+
2241
+			// if new page set asked
2242
+			if ($newPageSet) {
2243
+				$this->_subHEADER = array();
2244
+				$this->_subFOOTER = array();
2245
+
2246
+				// orientation
2247
+				$orientation = '';
2248
+				if (isset($param['orientation'])) {
2249
+					$param['orientation'] = strtolower($param['orientation']);
2250
+					if ($param['orientation']=='p')         $orientation = 'P';
2251
+					if ($param['orientation']=='portrait')  $orientation = 'P';
2252
+
2253
+					if ($param['orientation']=='l')         $orientation = 'L';
2254
+					if ($param['orientation']=='paysage')   $orientation = 'L';
2255
+					if ($param['orientation']=='landscape') $orientation = 'L';
2256
+				}
2257
+
2258
+				// format
2259
+				$format = null;
2260
+				if (isset($param['format'])) {
2261
+					$format = strtolower($param['format']);
2262
+					if (preg_match('/^([0-9]+)x([0-9]+)$/isU', $format, $match)) {
2263
+						$format = array(intval($match[1]), intval($match[2]));
2264
+					}
2265
+				}
2266
+
2267
+				// background
2268
+				$background = array();
2269
+				if (isset($param['backimg'])) {
2270
+					$background['img']    = isset($param['backimg'])  ? $param['backimg']  : '';       // src of the image
2271
+					$background['posX']   = isset($param['backimgx']) ? $param['backimgx'] : 'center'; // horizontale position of the image
2272
+					$background['posY']   = isset($param['backimgy']) ? $param['backimgy'] : 'middle'; // vertical position of the image
2273
+					$background['width']  = isset($param['backimgw']) ? $param['backimgw'] : '100%';   // width of the image (100% = page width)
2274
+
2275
+					// convert the src of the image, if parameters
2276
+					$background['img'] = str_replace('&amp;', '&', $background['img']);
2277
+
2278
+					// convert the positions
2279
+					if ($background['posX']=='left')    $background['posX'] = '0%';
2280
+					if ($background['posX']=='center')  $background['posX'] = '50%';
2281
+					if ($background['posX']=='right')   $background['posX'] = '100%';
2282
+					if ($background['posY']=='top')     $background['posY'] = '0%';
2283
+					if ($background['posY']=='middle')  $background['posY'] = '50%';
2284
+					if ($background['posY']=='bottom')  $background['posY'] = '100%';
2285
+
2286
+					if ($background['img']) {
2287
+						// get the size of the image
2288
+						// WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
2289
+						$infos=@getimagesize($background['img']);
2290
+						if (count($infos)>1) {
2291
+							$imageWidth = $this->parsingCss->ConvertToMM($background['width'], $this->pdf->getW());
2292
+							$imageHeight = $imageWidth*$infos[1]/$infos[0];
2293
+
2294
+							$background['width'] = $imageWidth;
2295
+							$background['posX']  = $this->parsingCss->ConvertToMM($background['posX'], $this->pdf->getW() - $imageWidth);
2296
+							$background['posY']  = $this->parsingCss->ConvertToMM($background['posY'], $this->pdf->getH() - $imageHeight);
2297
+						} else {
2298
+							$background = array();
2299
+						}
2300
+					} else {
2301
+						$background = array();
2302
+					}
2303
+				}
2304
+
2305
+				// margins of the page
2306
+				$background['top']    = isset($param['backtop'])    ? $param['backtop']    : '0';
2307
+				$background['bottom'] = isset($param['backbottom']) ? $param['backbottom'] : '0';
2308
+				$background['left']   = isset($param['backleft'])   ? $param['backleft']   : '0';
2309
+				$background['right']  = isset($param['backright'])  ? $param['backright']  : '0';
2310
+
2311
+				// if no unit => mm
2312
+				if (preg_match('/^([0-9]*)$/isU', $background['top']))    $background['top']    .= 'mm';
2313
+				if (preg_match('/^([0-9]*)$/isU', $background['bottom'])) $background['bottom'] .= 'mm';
2314
+				if (preg_match('/^([0-9]*)$/isU', $background['left']))   $background['left']   .= 'mm';
2315
+				if (preg_match('/^([0-9]*)$/isU', $background['right']))  $background['right']  .= 'mm';
2316
+
2317
+				// convert to mm
2318
+				$background['top']    = $this->parsingCss->ConvertToMM($background['top'], $this->pdf->getH());
2319
+				$background['bottom'] = $this->parsingCss->ConvertToMM($background['bottom'], $this->pdf->getH());
2320
+				$background['left']   = $this->parsingCss->ConvertToMM($background['left'], $this->pdf->getW());
2321
+				$background['right']  = $this->parsingCss->ConvertToMM($background['right'], $this->pdf->getW());
2322
+
2323
+				// get the background color
2324
+				$res = false;
2325
+				$background['color']    = isset($param['backcolor'])    ? $this->parsingCss->convertToColor($param['backcolor'], $res) : null;
2326
+				if (!$res) $background['color'] = null;
2327
+
2328
+				$this->parsingCss->save();
2329
+				$this->parsingCss->analyse('PAGE', $param);
2330
+				$this->parsingCss->setPosition();
2331
+				$this->parsingCss->fontSet();
2332
+
2333
+				// new page
2334
+				$this->_setNewPage($format, $orientation, $background, null, $resetPageNumber);
2335
+
2336
+				// automatic footer
2337
+				if (isset($param['footer'])) {
2338
+					$lst = explode(';', $param['footer']);
2339
+					foreach ($lst as $key => $val) $lst[$key] = trim(strtolower($val));
2340
+					$page    = in_array('page', $lst);
2341
+					$date    = in_array('date', $lst);
2342
+					$hour    = in_array('heure', $lst);
2343
+					$form    = in_array('form', $lst);
2344
+				} else {
2345
+					$page    = null;
2346
+					$date    = null;
2347
+					$hour    = null;
2348
+					$form    = null;
2349
+				}
2350
+				$this->pdf->SetMyFooter($page, $date, $hour, $form);
2351
+			// else => we use the last page set used
2352
+			} else {
2353
+				$this->parsingCss->save();
2354
+				$this->parsingCss->analyse('PAGE', $param);
2355
+				$this->parsingCss->setPosition();
2356
+				$this->parsingCss->fontSet();
2357
+
2358
+				$this->_setNewPage(null, null, null, null, $resetPageNumber);
2359
+			}
2360
+
2361
+			return true;
2362
+		}
2363
+
2364
+		/**
2365
+		 * tag : PAGE
2366
+		 * mode : CLOSE
2367
+		 *
2368
+		 * @param  array $param
2369
+		 * @return boolean
2370
+		 */
2371
+		protected function _tag_close_PAGE($param)
2372
+		{
2373
+			if ($this->_isForOneLine) return false;
2374
+
2375
+			$this->_maxH = 0;
2376
+
2377
+			$this->parsingCss->load();
2378
+			$this->parsingCss->fontSet();
2379
+
2380
+			if ($this->_debugActif) $this->_DEBUG_add('PAGE '.$this->_page, false);
2381
+
2382
+			return true;
2383
+		}
2384
+
2385
+		/**
2386
+		 * tag : PAGE_HEADER
2387
+		 * mode : OPEN
2388
+		 *
2389
+		 * @param  array $param
2390
+		 * @return boolean
2391
+		 */
2392
+		protected function _tag_open_PAGE_HEADER($param)
2393
+		{
2394
+			if ($this->_isForOneLine) return false;
2395
+
2396
+			$this->_subHEADER = array();
2397
+			for ($this->_parsePos; $this->_parsePos<count($this->parsingHtml->code); $this->_parsePos++) {
2398
+				$action = $this->parsingHtml->code[$this->_parsePos];
2399
+				if ($action['name']=='page_header') $action['name']='page_header_sub';
2400
+				$this->_subHEADER[] = $action;
2401
+				if (strtolower($action['name'])=='page_header_sub' && $action['close']) break;
2402
+			}
2403
+
2404
+			$this->_setPageHeader();
2405
+
2406
+			return true;
2407
+		}
2408
+
2409
+		/**
2410
+		 * tag : PAGE_FOOTER
2411
+		 * mode : OPEN
2412
+		 *
2413
+		 * @param  array $param
2414
+		 * @return boolean
2415
+		 */
2416
+		protected function _tag_open_PAGE_FOOTER($param)
2417
+		{
2418
+			if ($this->_isForOneLine) return false;
2419
+
2420
+			$this->_subFOOTER = array();
2421
+			for ($this->_parsePos; $this->_parsePos<count($this->parsingHtml->code); $this->_parsePos++) {
2422
+				$action = $this->parsingHtml->code[$this->_parsePos];
2423
+				if ($action['name']=='page_footer') $action['name']='page_footer_sub';
2424
+				$this->_subFOOTER[] = $action;
2425
+				if (strtolower($action['name'])=='page_footer_sub' && $action['close']) break;
2426
+			}
2427
+
2428
+			$this->_setPageFooter();
2429
+
2430
+			return true;
2431
+		}
2432
+
2433
+		/**
2434
+		 * It is not a real tag. Does not use it directly
2435
+		 *
2436
+		 * @param  array $param
2437
+		 * @return boolean
2438
+		 */
2439
+		protected function _tag_open_PAGE_HEADER_SUB($param)
2440
+		{
2441
+			if ($this->_isForOneLine) return false;
2442
+
2443
+			// save the current stat
2444
+			$this->_subSTATES = array();
2445
+			$this->_subSTATES['x']  = $this->pdf->getX();
2446
+			$this->_subSTATES['y']  = $this->pdf->getY();
2447
+			$this->_subSTATES['s']  = $this->parsingCss->value;
2448
+			$this->_subSTATES['t']  = $this->parsingCss->table;
2449
+			$this->_subSTATES['ml'] = $this->_margeLeft;
2450
+			$this->_subSTATES['mr'] = $this->_margeRight;
2451
+			$this->_subSTATES['mt'] = $this->_margeTop;
2452
+			$this->_subSTATES['mb'] = $this->_margeBottom;
2453
+			$this->_subSTATES['mp'] = $this->_pageMarges;
2454
+
2455
+			// new stat for the header
2456
+			$this->_pageMarges = array();
2457
+			$this->_margeLeft    = $this->_defaultLeft;
2458
+			$this->_margeRight   = $this->_defaultRight;
2459
+			$this->_margeTop     = $this->_defaultTop;
2460
+			$this->_margeBottom  = $this->_defaultBottom;
2461
+			$this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
2462
+			$this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
2463
+			$this->pdf->setXY($this->_defaultLeft, $this->_defaultTop);
2464
+
2465
+			$this->parsingCss->initStyle();
2466
+			$this->parsingCss->resetStyle();
2467
+			$this->parsingCss->value['width'] = $this->pdf->getW() - $this->_defaultLeft - $this->_defaultRight;
2468
+			$this->parsingCss->table = array();
2469
+
2470
+			$this->parsingCss->save();
2471
+			$this->parsingCss->analyse('page_header_sub', $param);
2472
+			$this->parsingCss->setPosition();
2473
+			$this->parsingCss->fontSet();
2474
+			$this->_setNewPositionForNewLine();
2475
+			return true;
2476
+		}
2477
+
2478
+		/**
2479
+		 * It is not a real tag. Does not use it directly
2480
+		 *
2481
+		 * @param  array $param
2482
+		 * @return boolean
2483
+		 */
2484
+		protected function _tag_close_PAGE_HEADER_SUB($param)
2485
+		{
2486
+			if ($this->_isForOneLine) return false;
2487
+
2488
+			$this->parsingCss->load();
2489
+
2490
+			// restore the stat
2491
+			$this->parsingCss->value = $this->_subSTATES['s'];
2492
+			$this->parsingCss->table = $this->_subSTATES['t'];
2493
+			$this->_pageMarges       = $this->_subSTATES['mp'];
2494
+			$this->_margeLeft        = $this->_subSTATES['ml'];
2495
+			$this->_margeRight       = $this->_subSTATES['mr'];
2496
+			$this->_margeTop         = $this->_subSTATES['mt'];
2497
+			$this->_margeBottom      = $this->_subSTATES['mb'];
2498
+			$this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
2499
+			$this->pdf->setbMargin($this->_margeBottom);
2500
+			$this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
2501
+			$this->pdf->setXY($this->_subSTATES['x'], $this->_subSTATES['y']);
2502
+
2503
+			$this->parsingCss->fontSet();
2504
+			$this->_maxH = 0;
2505
+
2506
+			return true;
2507
+		}
2508
+
2509
+		/**
2510
+		 * It is not a real tag. Does not use it directly
2511
+		 *
2512
+		 * @param  array $param
2513
+		 * @return boolean
2514
+		 */
2515
+		protected function _tag_open_PAGE_FOOTER_SUB($param)
2516
+		{
2517
+			if ($this->_isForOneLine) return false;
2518
+
2519
+			// save the current stat
2520
+			$this->_subSTATES = array();
2521
+			$this->_subSTATES['x']    = $this->pdf->getX();
2522
+			$this->_subSTATES['y']    = $this->pdf->getY();
2523
+			$this->_subSTATES['s']    = $this->parsingCss->value;
2524
+			$this->_subSTATES['t']    = $this->parsingCss->table;
2525
+			$this->_subSTATES['ml']    = $this->_margeLeft;
2526
+			$this->_subSTATES['mr']    = $this->_margeRight;
2527
+			$this->_subSTATES['mt']    = $this->_margeTop;
2528
+			$this->_subSTATES['mb']    = $this->_margeBottom;
2529
+			$this->_subSTATES['mp']    = $this->_pageMarges;
2530
+
2531
+			// new stat for the footer
2532
+			$this->_pageMarges  = array();
2533
+			$this->_margeLeft   = $this->_defaultLeft;
2534
+			$this->_margeRight  = $this->_defaultRight;
2535
+			$this->_margeTop    = $this->_defaultTop;
2536
+			$this->_margeBottom = $this->_defaultBottom;
2537
+			$this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
2538
+			$this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
2539
+			$this->pdf->setXY($this->_defaultLeft, $this->_defaultTop);
2540
+
2541
+			$this->parsingCss->initStyle();
2542
+			$this->parsingCss->resetStyle();
2543
+			$this->parsingCss->value['width']    = $this->pdf->getW() - $this->_defaultLeft - $this->_defaultRight;
2544
+			$this->parsingCss->table                = array();
2545
+
2546
+			// we create a sub HTML2PFDF, and we execute on it the content of the footer, to get the height of it
2547
+			$sub = null;
2548
+			$this->_createSubHTML($sub);
2549
+			$sub->parsingHtml->code = $this->parsingHtml->getLevel($this->_parsePos);
2550
+			$sub->_makeHTMLcode();
2551
+			$this->pdf->setY($this->pdf->getH() - $sub->_maxY - $this->_defaultBottom - 0.01);
2552
+			$this->_destroySubHTML($sub);
2553
+
2554
+			$this->parsingCss->save();
2555
+			$this->parsingCss->analyse('page_footer_sub', $param);
2556
+			$this->parsingCss->setPosition();
2557
+			$this->parsingCss->fontSet();
2558
+			$this->_setNewPositionForNewLine();
2559
+
2560
+			return true;
2561
+		}
2562
+
2563
+		/**
2564
+		 * It is not a real tag. Does not use it directly
2565
+		 *
2566
+		 * @param  array $param
2567
+		 * @return boolean
2568
+		 */
2569
+		protected function _tag_close_PAGE_FOOTER_SUB($param)
2570
+		{
2571
+			if ($this->_isForOneLine) return false;
2572
+
2573
+			$this->parsingCss->load();
2574
+
2575
+			$this->parsingCss->value                = $this->_subSTATES['s'];
2576
+			$this->parsingCss->table                = $this->_subSTATES['t'];
2577
+			$this->_pageMarges                 = $this->_subSTATES['mp'];
2578
+			$this->_margeLeft                = $this->_subSTATES['ml'];
2579
+			$this->_margeRight                = $this->_subSTATES['mr'];
2580
+			$this->_margeTop                    = $this->_subSTATES['mt'];
2581
+			$this->_margeBottom                = $this->_subSTATES['mb'];
2582
+			$this->pdf->SetMargins($this->_margeLeft, $this->_margeTop, $this->_margeRight);
2583
+			$this->pdf->SetAutoPageBreak(false, $this->_margeBottom);
2584
+			$this->pdf->setXY($this->_subSTATES['x'], $this->_subSTATES['y']);
2585
+
2586
+			$this->parsingCss->fontSet();
2587
+			$this->_maxH = 0;
2588
+
2589
+			return true;
2590
+		}
2591
+
2592
+		/**
2593
+		 * tag : NOBREAK
2594
+		 * mode : OPEN
2595
+		 *
2596
+		 * @param  array $param
2597
+		 * @return boolean
2598
+		 */
2599
+		protected function _tag_open_NOBREAK($param)
2600
+		{
2601
+			if ($this->_isForOneLine) return false;
2602
+
2603
+			$this->_maxH = 0;
2604
+
2605
+			// create a sub HTML2PDF to execute the content of the tag, to get the dimensions
2606
+			$sub = null;
2607
+			$this->_createSubHTML($sub);
2608
+			$sub->parsingHtml->code = $this->parsingHtml->getLevel($this->_parsePos);
2609
+			$sub->_makeHTMLcode();
2610
+			$y = $this->pdf->getY();
2611
+
2612
+			// if the content does not fit on the page => new page
2613
+			if (
2614
+				$sub->_maxY < ($this->pdf->getH() - $this->pdf->gettMargin()-$this->pdf->getbMargin()) &&
2615
+				$y + $sub->_maxY>=($this->pdf->getH() - $this->pdf->getbMargin())
2616
+			) {
2617
+				$this->_setNewPage();
2618
+			}
2619
+
2620
+			// destroy the sub HTML2PDF
2621
+			$this->_destroySubHTML($sub);
2622
+
2623
+			return true;
2624
+		}
2625
+
2626
+
2627
+		/**
2628
+		 * tag : NOBREAK
2629
+		 * mode : CLOSE
2630
+		 *
2631
+		 * @param  array $param
2632
+		 * @return boolean
2633
+		 */
2634
+		protected function _tag_close_NOBREAK($param)
2635
+		{
2636
+			if ($this->_isForOneLine) return false;
2637
+
2638
+			$this->_maxH = 0;
2639
+
2640
+			return true;
2641
+		}
2642
+
2643
+		/**
2644
+		 * tag : DIV
2645
+		 * mode : OPEN
2646
+		 *
2647
+		 * @param  array $param
2648
+		 * @param  string $other name of tag that used the div tag
2649
+		 * @return boolean
2650
+		 */
2651
+		protected function _tag_open_DIV($param, $other = 'div')
2652
+		{
2653
+			if ($this->_isForOneLine) return false;
2654
+			if ($this->_debugActif) $this->_DEBUG_add(strtoupper($other), true);
2655
+
2656
+			$this->parsingCss->save();
2657
+			$this->parsingCss->analyse($other, $param);
2658
+			$this->parsingCss->fontSet();
2659
+
2660
+			// for fieldset and legend
2661
+			if (in_array($other, array('fieldset', 'legend'))) {
2662
+				if (isset($param['moveTop']))  $this->parsingCss->value['margin']['t']    += $param['moveTop'];
2663
+				if (isset($param['moveLeft'])) $this->parsingCss->value['margin']['l']    += $param['moveLeft'];
2664
+				if (isset($param['moveDown'])) $this->parsingCss->value['margin']['b']    += $param['moveDown'];
2665
+			}
2666
+
2667
+			$alignObject = null;
2668
+			if ($this->parsingCss->value['margin-auto']) $alignObject = 'center';
2669
+
2670
+			$marge = array();
2671
+			$marge['l'] = $this->parsingCss->value['border']['l']['width'] + $this->parsingCss->value['padding']['l']+0.03;
2672
+			$marge['r'] = $this->parsingCss->value['border']['r']['width'] + $this->parsingCss->value['padding']['r']+0.03;
2673
+			$marge['t'] = $this->parsingCss->value['border']['t']['width'] + $this->parsingCss->value['padding']['t']+0.03;
2674
+			$marge['b'] = $this->parsingCss->value['border']['b']['width'] + $this->parsingCss->value['padding']['b']+0.03;
2675
+
2676
+			// extract the content of the div
2677
+			$level = $this->parsingHtml->getLevel($this->_parsePos);
2678
+
2679
+			// create a sub HTML2PDF to get the dimensions of the content of the div
2680
+			$w = 0; $h = 0;
2681
+			if (count($level)) {
2682
+				$sub = null;
2683
+				$this->_createSubHTML($sub);
2684
+				$sub->parsingHtml->code = $level;
2685
+				$sub->_makeHTMLcode();
2686
+				$w = $sub->_maxX;
2687
+				$h = $sub->_maxY;
2688
+				$this->_destroySubHTML($sub);
2689
+			}
2690
+			$wReel = $w;
2691
+			$hReel = $h;
2692
+
2693
+			$w+= $marge['l']+$marge['r']+0.001;
2694
+			$h+= $marge['t']+$marge['b']+0.001;
2695
+
2696
+			if ($this->parsingCss->value['overflow']=='hidden') {
2697
+				$overW = max($w, $this->parsingCss->value['width']);
2698
+				$overH = max($h, $this->parsingCss->value['height']);
2699
+				$overflow = true;
2700
+				$this->parsingCss->value['old_maxX'] = $this->_maxX;
2701
+				$this->parsingCss->value['old_maxY'] = $this->_maxY;
2702
+				$this->parsingCss->value['old_maxH'] = $this->_maxH;
2703
+				$this->parsingCss->value['old_overflow'] = $this->_isInOverflow;
2704
+				$this->_isInOverflow = true;
2705
+			} else {
2706
+				$overW = null;
2707
+				$overH = null;
2708
+				$overflow = false;
2709
+				$this->parsingCss->value['width']    = max($w, $this->parsingCss->value['width']);
2710
+				$this->parsingCss->value['height']    = max($h, $this->parsingCss->value['height']);
2711
+			}
2712
+
2713
+			switch($this->parsingCss->value['rotate'])
2714
+			{
2715
+				case 90:
2716
+					$tmp = $overH; $overH = $overW; $overW = $tmp;
2717
+					$tmp = $hReel; $hReel = $wReel; $wReel = $tmp;
2718
+					unset($tmp);
2719
+					$w = $this->parsingCss->value['height'];
2720
+					$h = $this->parsingCss->value['width'];
2721
+					$tX =-$h;
2722
+					$tY = 0;
2723
+					break;
2724
+
2725
+				case 180:
2726
+					$w = $this->parsingCss->value['width'];
2727
+					$h = $this->parsingCss->value['height'];
2728
+					$tX = -$w;
2729
+					$tY = -$h;
2730
+					break;
2731
+
2732
+				case 270:
2733
+					$tmp = $overH; $overH = $overW; $overW = $tmp;
2734
+					$tmp = $hReel; $hReel = $wReel; $wReel = $tmp;
2735
+					unset($tmp);
2736
+					$w = $this->parsingCss->value['height'];
2737
+					$h = $this->parsingCss->value['width'];
2738
+					$tX = 0;
2739
+					$tY =-$w;
2740
+					break;
2741
+
2742
+				default:
2743
+					$w = $this->parsingCss->value['width'];
2744
+					$h = $this->parsingCss->value['height'];
2745
+					$tX = 0;
2746
+					$tY = 0;
2747
+					break;
2748
+			}
2749
+
2750
+			if (!$this->parsingCss->value['position']) {
2751
+				if (
2752
+					$w < ($this->pdf->getW() - $this->pdf->getlMargin()-$this->pdf->getrMargin()) &&
2753
+					$this->pdf->getX() + $w>=($this->pdf->getW() - $this->pdf->getrMargin())
2754
+					)
2755
+					$this->_tag_open_BR(array());
2756
+
2757
+				if (
2758
+						($h < ($this->pdf->getH() - $this->pdf->gettMargin()-$this->pdf->getbMargin())) &&
2759
+						($this->pdf->getY() + $h>=($this->pdf->getH() - $this->pdf->getbMargin())) &&
2760
+						!$this->_isInOverflow
2761
+					)
2762
+					$this->_setNewPage();
2763
+
2764
+				$old = $this->parsingCss->getOldValues();
2765
+				$parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
2766
+
2767
+				if ($parentWidth>$w) {
2768
+					if ($alignObject=='center')        $this->pdf->setX($this->pdf->getX() + ($parentWidth-$w)*0.5);
2769
+					else if ($alignObject=='right')    $this->pdf->setX($this->pdf->getX() + $parentWidth-$w);
2770
+				}
2771
+
2772
+				$this->parsingCss->setPosition();
2773
+			} else {
2774
+				$old = $this->parsingCss->getOldValues();
2775
+				$parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
2776
+
2777
+				if ($parentWidth>$w) {
2778
+					if ($alignObject=='center')        $this->pdf->setX($this->pdf->getX() + ($parentWidth-$w)*0.5);
2779
+					else if ($alignObject=='right')    $this->pdf->setX($this->pdf->getX() + $parentWidth-$w);
2780
+				}
2781
+
2782
+				$this->parsingCss->setPosition();
2783
+				$this->_saveMax();
2784
+				$this->_maxX = 0;
2785
+				$this->_maxY = 0;
2786
+				$this->_maxH = 0;
2787
+				$this->_maxE = 0;
2788
+			}
2789
+
2790
+			if ($this->parsingCss->value['rotate']) {
2791
+				$this->pdf->startTransform();
2792
+				$this->pdf->setRotation($this->parsingCss->value['rotate']);
2793
+				$this->pdf->setTranslate($tX, $tY);
2794
+			}
2795
+
2796
+			$this->_drawRectangle(
2797
+				$this->parsingCss->value['x'],
2798
+				$this->parsingCss->value['y'],
2799
+				$this->parsingCss->value['width'],
2800
+				$this->parsingCss->value['height'],
2801
+				$this->parsingCss->value['border'],
2802
+				$this->parsingCss->value['padding'],
2803
+				0,
2804
+				$this->parsingCss->value['background']
2805
+			);
2806
+
2807
+			$marge = array();
2808
+			$marge['l'] = $this->parsingCss->value['border']['l']['width'] + $this->parsingCss->value['padding']['l']+0.03;
2809
+			$marge['r'] = $this->parsingCss->value['border']['r']['width'] + $this->parsingCss->value['padding']['r']+0.03;
2810
+			$marge['t'] = $this->parsingCss->value['border']['t']['width'] + $this->parsingCss->value['padding']['t']+0.03;
2811
+			$marge['b'] = $this->parsingCss->value['border']['b']['width'] + $this->parsingCss->value['padding']['b']+0.03;
2812
+
2813
+			$this->parsingCss->value['width'] -= $marge['l']+$marge['r'];
2814
+			$this->parsingCss->value['height']-= $marge['t']+$marge['b'];
2815
+
2816
+			$xCorr = 0;
2817
+			$yCorr = 0;
2818
+			if (!$this->_subPart && !$this->_isSubPart) {
2819
+				switch($this->parsingCss->value['text-align'])
2820
+				{
2821
+					case 'right':
2822
+						$xCorr = ($this->parsingCss->value['width']-$wReel);
2823
+						break;
2824
+					case 'center':
2825
+						$xCorr = ($this->parsingCss->value['width']-$wReel)*0.5;
2826
+						break;
2827
+				}
2828
+				if ($xCorr>0) $xCorr=0;
2829
+				switch($this->parsingCss->value['vertical-align'])
2830
+				{
2831
+					case 'bottom':
2832
+						$yCorr = ($this->parsingCss->value['height']-$hReel);
2833
+						break;
2834
+					case 'middle':
2835
+						$yCorr = ($this->parsingCss->value['height']-$hReel)*0.5;
2836
+						break;
2837
+				}
2838
+			}
2839
+
2840
+			if ($overflow) {
2841
+				$overW-= $marge['l']+$marge['r'];
2842
+				$overH-= $marge['t']+$marge['b'];
2843
+				$this->pdf->clippingPathStart(
2844
+					$this->parsingCss->value['x']+$marge['l'],
2845
+					$this->parsingCss->value['y']+$marge['t'],
2846
+					$this->parsingCss->value['width'],
2847
+					$this->parsingCss->value['height']
2848
+				);
2849
+
2850
+				$this->parsingCss->value['x']+= $xCorr;
2851
+
2852
+				// marges from the dimension of the content
2853
+				$mL = $this->parsingCss->value['x']+$marge['l'];
2854
+				$mR = $this->pdf->getW() - $mL - $overW;
2855
+			} else {
2856
+				// marges from the dimension of the div
2857
+				$mL = $this->parsingCss->value['x']+$marge['l'];
2858
+				$mR = $this->pdf->getW() - $mL - $this->parsingCss->value['width'];
2859
+			}
2860
+
2861
+			$x = $this->parsingCss->value['x']+$marge['l'];
2862
+			$y = $this->parsingCss->value['y']+$marge['t']+$yCorr;
2863
+			$this->_saveMargin($mL, 0, $mR);
2864
+			$this->pdf->setXY($x, $y);
2865
+
2866
+			$this->_setNewPositionForNewLine();
2867
+
2868
+			return true;
2869
+		}
2870
+
2871
+		/**
2872
+		 * tag : BLOCKQUOTE
2873
+		 * mode : OPEN
2874
+		 *
2875
+		 * @param  array $param
2876
+		 * @return boolean
2877
+		 */
2878
+		protected function _tag_open_BLOCKQUOTE($param)
2879
+		{
2880
+			return $this->_tag_open_DIV($param, 'blockquote');
2881
+		}
2882
+
2883
+		/**
2884
+		 * tag : LEGEND
2885
+		 * mode : OPEN
2886
+		 *
2887
+		 * @param  array $param
2888
+		 * @return boolean
2889
+		 */
2890
+		protected function _tag_open_LEGEND($param)
2891
+		{
2892
+			return $this->_tag_open_DIV($param, 'legend');
2893
+		}
2894
+
2895
+		/**
2896
+		 * tag : FIELDSET
2897
+		 * mode : OPEN
2898
+		 *
2899
+		 * @author Pavel Kochman
2900
+		 * @param  array $param
2901
+		 * @return boolean
2902
+		 */
2903
+		protected function _tag_open_FIELDSET($param)
2904
+		{
2905
+
2906
+			$this->parsingCss->save();
2907
+			$this->parsingCss->analyse('fieldset', $param);
2908
+
2909
+			// get height of LEGEND element and make fieldset corrections
2910
+			for ($tempPos = $this->_parsePos + 1; $tempPos<count($this->parsingHtml->code); $tempPos++) {
2911
+				$action = $this->parsingHtml->code[$tempPos];
2912
+				if ($action['name'] == 'fieldset') break;
2913
+				if ($action['name'] == 'legend' && !$action['close']) {
2914
+					$legendOpenPos = $tempPos;
2915
+
2916
+					$sub = null;
2917
+					$this->_createSubHTML($sub);
2918
+					$sub->parsingHtml->code = $this->parsingHtml->getLevel($tempPos - 1);
2919
+
2920
+					$res = null;
2921
+					for ($sub->_parsePos = 0; $sub->_parsePos<count($sub->parsingHtml->code); $sub->_parsePos++) {
2922
+						$action = $sub->parsingHtml->code[$sub->_parsePos];
2923
+						$sub->_executeAction($action);
2924
+
2925
+						if ($action['name'] == 'legend' && $action['close'])
2926
+							break;
2927
+					}
2928
+
2929
+					$legendH = $sub->_maxY;
2930
+					$this->_destroySubHTML($sub);
2931
+
2932
+					$move = $this->parsingCss->value['padding']['t'] + $this->parsingCss->value['border']['t']['width'] + 0.03;
2933
+
2934
+					$param['moveTop'] = $legendH / 2;
2935
+
2936
+					$this->parsingHtml->code[$legendOpenPos]['param']['moveTop'] = - ($legendH / 2 + $move);
2937
+					$this->parsingHtml->code[$legendOpenPos]['param']['moveLeft'] = 2 - $this->parsingCss->value['border']['l']['width'] - $this->parsingCss->value['padding']['l'];
2938
+					$this->parsingHtml->code[$legendOpenPos]['param']['moveDown'] = $move;
2939
+					break;
2940
+				}
2941
+			}
2942
+			$this->parsingCss->load();
2943
+
2944
+			return $this->_tag_open_DIV($param, 'fieldset');
2945
+		}
2946
+
2947
+		/**
2948
+		 * tag : DIV
2949
+		 * mode : CLOSE
2950
+		 *
2951
+		 * @param  array $param
2952
+		 * @param  string $other name of tag that used the div tag
2953
+		 * @return boolean
2954
+		 */
2955
+		protected function _tag_close_DIV($param, $other='div')
2956
+		{
2957
+			if ($this->_isForOneLine) return false;
2958
+
2959
+			if ($this->parsingCss->value['overflow']=='hidden') {
2960
+				$this->_maxX = $this->parsingCss->value['old_maxX'];
2961
+				$this->_maxY = $this->parsingCss->value['old_maxY'];
2962
+				$this->_maxH = $this->parsingCss->value['old_maxH'];
2963
+				$this->_isInOverflow = $this->parsingCss->value['old_overflow'];
2964
+				$this->pdf->clippingPathStop();
2965
+			}
2966
+
2967
+			if ($this->parsingCss->value['rotate'])
2968
+				$this->pdf->stopTransform();
2969
+
2970
+			$marge = array();
2971
+			$marge['l'] = $this->parsingCss->value['border']['l']['width'] + $this->parsingCss->value['padding']['l']+0.03;
2972
+			$marge['r'] = $this->parsingCss->value['border']['r']['width'] + $this->parsingCss->value['padding']['r']+0.03;
2973
+			$marge['t'] = $this->parsingCss->value['border']['t']['width'] + $this->parsingCss->value['padding']['t']+0.03;
2974
+			$marge['b'] = $this->parsingCss->value['border']['b']['width'] + $this->parsingCss->value['padding']['b']+0.03;
2975
+
2976
+			$x = $this->parsingCss->value['x'];
2977
+			$y = $this->parsingCss->value['y'];
2978
+			$w = $this->parsingCss->value['width']+$marge['l']+$marge['r']+$this->parsingCss->value['margin']['r'];
2979
+			$h = $this->parsingCss->value['height']+$marge['t']+$marge['b']+$this->parsingCss->value['margin']['b'];
2980
+
2981
+			switch($this->parsingCss->value['rotate'])
2982
+			{
2983
+				case 90:
2984
+					$t = $w; $w = $h; $h = $t;
2985
+					break;
2986
+
2987
+				case 270:
2988
+					$t = $w; $w = $h; $h = $t;
2989
+					break;
2990
+
2991
+				default:
2992
+					break;
2993
+			}
2994
+
2995
+
2996
+			if ($this->parsingCss->value['position']!='absolute') {
2997
+				$this->pdf->setXY($x+$w, $y);
2998
+
2999
+				$this->_maxX = max($this->_maxX, $x+$w);
3000
+				$this->_maxY = max($this->_maxY, $y+$h);
3001
+				$this->_maxH = max($this->_maxH, $h);
3002
+			} else {
3003
+				$this->pdf->setXY($this->parsingCss->value['xc'], $this->parsingCss->value['yc']);
3004
+
3005
+				$this->_loadMax();
3006
+			}
3007
+
3008
+			$block = ($this->parsingCss->value['display']!='inline' && $this->parsingCss->value['position']!='absolute');
3009
+
3010
+			$this->parsingCss->load();
3011
+			$this->parsingCss->fontSet();
3012
+			$this->_loadMargin();
3013
+
3014
+			if ($block) $this->_tag_open_BR(array());
3015
+			if ($this->_debugActif) $this->_DEBUG_add(strtoupper($other), false);
3016
+
3017
+			return true;
3018
+		}
3019
+
3020
+		/**
3021
+		 * tag : BLOCKQUOTE
3022
+		 * mode : CLOSE
3023
+		 *
3024
+		 * @param  array $param
3025
+		 * @return boolean
3026
+		 */
3027
+		protected function _tag_close_BLOCKQUOTE($param)
3028
+		{
3029
+			return $this->_tag_close_DIV($param, 'blockquote');
3030
+		}
3031
+
3032
+		/**
3033
+		 * tag : FIELDSET
3034
+		 * mode : CLOSE
3035
+		 *
3036
+		 * @param  array $param
3037
+		 * @return boolean
3038
+		 */
3039
+		protected function _tag_close_FIELDSET($param)
3040
+		{
3041
+			return $this->_tag_close_DIV($param, 'fieldset');
3042
+		}
3043
+
3044
+		/**
3045
+		 * tag : LEGEND
3046
+		 * mode : CLOSE
3047
+		 *
3048
+		 * @param  array $param
3049
+		 * @return boolean
3050
+		 */
3051
+		protected function _tag_close_LEGEND($param)
3052
+		{
3053
+			return $this->_tag_close_DIV($param, 'legend');
3054
+		}
3055
+
3056
+		/**
3057
+		 * tag : BARCODE
3058
+		 * mode : OPEN
3059
+		 *
3060
+		 * @param  array $param
3061
+		 * @return boolean
3062
+		 */
3063
+		protected function _tag_open_BARCODE($param)
3064
+		{
3065
+			// for  compatibility with old versions < 3.29
3066
+			$lstBarcode = array();
3067
+			$lstBarcode['UPC_A']  =    'UPCA';
3068
+			$lstBarcode['CODE39'] =    'C39';
3069
+
3070
+			if (!isset($param['type']))     $param['type'] = 'C39';
3071
+			if (!isset($param['value']))    $param['value']    = 0;
3072
+			if (!isset($param['label']))    $param['label']    = 'label';
3073
+			if (!isset($param['style']['color'])) $param['style']['color'] = '#000000';
3074
+
3075
+			if ($this->_testIsDeprecated && (isset($param['bar_h']) || isset($param['bar_w'])))
3076
+				throw new HTML2PDF_exception(9, array('BARCODE', 'bar_h, bar_w'));
3077
+
3078
+			$param['type'] = strtoupper($param['type']);
3079
+			if (isset($lstBarcode[$param['type']])) $param['type'] = $lstBarcode[$param['type']];
3080
+
3081
+			$this->parsingCss->save();
3082
+			$this->parsingCss->analyse('barcode', $param);
3083
+			$this->parsingCss->setPosition();
3084
+			$this->parsingCss->fontSet();
3085
+
3086
+			$x = $this->pdf->getX();
3087
+			$y = $this->pdf->getY();
3088
+			$w = $this->parsingCss->value['width'];    if (!$w) $w = $this->parsingCss->ConvertToMM('50mm');
3089
+			$h = $this->parsingCss->value['height'];    if (!$h) $h = $this->parsingCss->ConvertToMM('10mm');
3090
+			$txt = ($param['label']!=='none' ? $this->parsingCss->value['font-size'] : false);
3091
+			$c = $this->parsingCss->value['color'];
3092
+			$infos = $this->pdf->myBarcode($param['value'], $param['type'], $x, $y, $w, $h, $txt, $c);
3093
+
3094
+			$this->_maxX = max($this->_maxX, $x+$infos[0]);
3095
+			$this->_maxY = max($this->_maxY, $y+$infos[1]);
3096
+			$this->_maxH = max($this->_maxH, $infos[1]);
3097
+			$this->_maxE++;
3098
+
3099
+			$this->pdf->setXY($x+$infos[0], $y);
3100
+
3101
+			$this->parsingCss->load();
3102
+			$this->parsingCss->fontSet();
3103
+
3104
+			return true;
3105
+		}
3106
+
3107
+		/**
3108
+		 * tag : BARCODE
3109
+		 * mode : CLOSE
3110
+		 *
3111
+		 * @param  array $param
3112
+		 * @return boolean
3113
+		 */
3114
+		protected function _tag_close_BARCODE($param)
3115
+		{
3116
+			// there is nothing to do here
3117
+
3118
+			return true;
3119
+		}
3120
+
3121
+		/**
3122
+		 * tag : QRCODE
3123
+		 * mode : OPEN
3124
+		 *
3125
+		 * @param  array $param
3126
+		 * @return boolean
3127
+		 */
3128
+		protected function _tag_open_QRCODE($param)
3129
+		{
3130
+			if ($this->_testIsDeprecated && (isset($param['size']) || isset($param['noborder'])))
3131
+				throw new HTML2PDF_exception(9, array('QRCODE', 'size, noborder'));
3132
+
3133
+			if ($this->_debugActif) $this->_DEBUG_add('QRCODE');
3134
+
3135
+			if (!isset($param['value']))                     $param['value'] = '';
3136
+			if (!isset($param['ec']))                        $param['ec'] = 'H';
3137
+			if (!isset($param['style']['color']))            $param['style']['color'] = '#000000';
3138
+			if (!isset($param['style']['background-color'])) $param['style']['background-color'] = '#FFFFFF';
3139
+			if (isset($param['style']['border'])) {
3140
+				$borders = $param['style']['border']!='none';
3141
+				unset($param['style']['border']);
3142
+			} else {
3143
+				$borders = true;
3144
+			}
3145
+
3146
+			if ($param['value']==='') return true;
3147
+			if (!in_array($param['ec'], array('L', 'M', 'Q', 'H'))) $param['ec'] = 'H';
3148
+
3149
+			$this->parsingCss->save();
3150
+			$this->parsingCss->analyse('qrcode', $param);
3151
+			$this->parsingCss->setPosition();
3152
+			$this->parsingCss->fontSet();
3153
+
3154
+			$x = $this->pdf->getX();
3155
+			$y = $this->pdf->getY();
3156
+			$w = $this->parsingCss->value['width'];
3157
+			$h = $this->parsingCss->value['height'];
3158
+			$size = max($w, $h); if (!$size) $size = $this->parsingCss->ConvertToMM('50mm');
3159
+
3160
+			$style = array(
3161
+					'fgcolor' => $this->parsingCss->value['color'],
3162
+					'bgcolor' => $this->parsingCss->value['background']['color'],
3163
+				);
3164
+
3165
+			if ($borders) {
3166
+				$style['border'] = true;
3167
+				$style['padding'] = 'auto';
3168
+			} else {
3169
+				$style['border'] = false;
3170
+				$style['padding'] = 0;
3171
+			}
3172
+
3173
+			if (!$this->_subPart && !$this->_isSubPart) {
3174
+				$this->pdf->write2DBarcode($param['value'], 'QRCODE,'.$param['ec'], $x, $y, $size, $size, $style);
3175
+			}
3176
+
3177
+			$this->_maxX = max($this->_maxX, $x+$size);
3178
+			$this->_maxY = max($this->_maxY, $y+$size);
3179
+			$this->_maxH = max($this->_maxH, $size);
3180
+			$this->_maxE++;
3181
+
3182
+			$this->pdf->setX($x+$size);
3183
+
3184
+			$this->parsingCss->load();
3185
+			$this->parsingCss->fontSet();
3186
+
3187
+			return true;
3188
+		}
3189
+
3190
+		/**
3191
+		 * tag : QRCODE
3192
+		 * mode : CLOSE
3193
+		 *
3194
+		 * @param  array $param
3195
+		 * @return boolean
3196
+		 */
3197
+		protected function _tag_close_QRCODE($param)
3198
+		{
3199
+			// there is nothing to do here
3200
+
3201
+			return true;
3202
+		}
3203
+
3204
+		/**
3205
+		 * tag : BOOKMARK
3206
+		 * mode : OPEN
3207
+		 *
3208
+		 * @param  array $param
3209
+		 * @return boolean
3210
+		 */
3211
+		protected function _tag_open_BOOKMARK($param)
3212
+		{
3213
+			$titre = isset($param['title']) ? trim($param['title']) : '';
3214
+			$level = isset($param['level']) ? floor($param['level']) : 0;
3215
+
3216
+			if ($level<0) $level = 0;
3217
+			if ($titre) $this->pdf->Bookmark($titre, $level, -1);
3218
+
3219
+			return true;
3220
+		}
3221
+
3222
+		/**
3223
+		 * tag : BOOKMARK
3224
+		 * mode : CLOSE
3225
+		 *
3226
+		 * @param  array $param
3227
+		 * @return boolean
3228
+		 */
3229
+		protected function _tag_close_BOOKMARK($param)
3230
+		{
3231
+			// there is nothing to do here
3232
+
3233
+			return true;
3234
+		}
3235
+
3236
+		/**
3237
+		 * this is not a real TAG, it is just to write texts
3238
+		 *
3239
+		 * @param  array $param
3240
+		 * @return boolean
3241
+		 */
3242
+		protected function _tag_open_WRITE($param)
3243
+		{
3244
+			$fill = ($this->parsingCss->value['background']['color']!==null && $this->parsingCss->value['background']['image']===null);
3245
+			if (in_array($this->parsingCss->value['id_tag'], array('fieldset', 'legend', 'div', 'table', 'tr', 'td', 'th'))) {
3246
+				$fill = false;
3247
+			}
3248
+
3249
+			// get the text to write
3250
+			$txt = $param['txt'];
3251
+
3252
+			if ($this->_isAfterFloat) {
3253
+				$txt = ltrim($txt);
3254
+				$this->_isAfterFloat = false;
3255
+			}
3256
+
3257
+			$txt = str_replace('[[page_nb]]', $this->pdf->getMyAliasNbPages(), $txt);
3258
+			$txt = str_replace('[[page_cu]]', $this->pdf->getMyNumPage($this->_page), $txt);
3259
+
3260
+			if ($this->parsingCss->value['text-transform']!='none') {
3261
+				if ($this->parsingCss->value['text-transform']=='capitalize')
3262
+					$txt = ucwords($txt);
3263
+				else if ($this->parsingCss->value['text-transform']=='uppercase')
3264
+					$txt = strtoupper($txt);
3265
+				else if ($this->parsingCss->value['text-transform']=='lowercase')
3266
+					$txt = strtolower($txt);
3267
+			}
3268
+
3269
+			// size of the text
3270
+			$h  = 1.08*$this->parsingCss->value['font-size'];
3271
+			$dh = $h*$this->parsingCss->value['mini-decal'];
3272
+			$lh = $this->parsingCss->getLineHeight();
3273
+
3274
+			// identify the align
3275
+			$align = 'L';
3276
+			if ($this->parsingCss->value['text-align']=='li_right') {
3277
+				$w = $this->parsingCss->value['width'];
3278
+				$align = 'R';
3279
+			}
3280
+
3281
+			// calculate the width of each words, and of all the sentence
3282
+			$w = 0;
3283
+			$words = explode(' ', $txt);
3284
+			foreach ($words as $k => $word) {
3285
+				$words[$k] = array($word, $this->pdf->GetStringWidth($word));
3286
+				$w+= $words[$k][1];
3287
+			}
3288
+			$space = $this->pdf->GetStringWidth(' ');
3289
+			$w+= $space*(count($words)-1);
3290
+
3291
+			// position in the text
3292
+			$currPos = 0;
3293
+
3294
+			// the bigger width of the text, after automatic break line
3295
+			$maxX = 0;
3296
+
3297
+			// position of the text
3298
+			$x = $this->pdf->getX();
3299
+			$y = $this->pdf->getY();
3300
+			$dy = $this->_getElementY($lh);
3301
+
3302
+			// margins
3303
+			list($left, $right) = $this->_getMargins($y);
3304
+
3305
+			// number of lines after automatic break line
3306
+			$nb = 0;
3307
+
3308
+			// while we have words, and the text does not fit on the line => we cut the sentence
3309
+			while ($x+$w>$right && $x<$right+$space && count($words)) {
3310
+				// adding words 1 by 1 to fit on the line
3311
+				$i=0;
3312
+				$old = array('', 0);
3313
+				$str = $words[0];
3314
+				$add = false;
3315
+				while (($x+$str[1])<$right) {
3316
+					$i++;
3317
+					$add = true;
3318
+
3319
+					array_shift($words);
3320
+					$old = $str;
3321
+
3322
+					if (!count($words)) break;
3323
+					$str[0].= ' '.$words[0][0];
3324
+					$str[1]+= $space+$words[0][1];
3325
+				}
3326
+				$str = $old;
3327
+
3328
+				// if  nothing fit on the line, and if the first word does not fit on the line => the word is too long, we put it
3329
+				if ($i==0 && (($left+$words[0][1])>=$right)) {
3330
+					$str = $words[0];
3331
+					array_shift($words);
3332
+					$i++;
3333
+					$add = true;
3334
+				}
3335
+				$currPos+= ($currPos ? 1 : 0)+strlen($str[0]);
3336
+
3337
+				// write the extract sentence that fit on the page
3338
+				$wc = ($align=='L' ? $str[1] : $this->parsingCss->value['width']);
3339
+				if ($right - $left<$wc) $wc = $right - $left;
3340
+
3341
+				if (strlen($str[0])) {
3342
+					$this->pdf->setXY($this->pdf->getX(), $y+$dh+$dy);
3343
+					$this->pdf->Cell($wc, $h, $str[0], 0, 0, $align, $fill, $this->_isInLink);
3344
+					$this->pdf->setXY($this->pdf->getX(), $y);
3345
+				}
3346
+				$this->_maxH = max($this->_maxH, $lh);
3347
+
3348
+				// max width
3349
+				$maxX = max($maxX, $this->pdf->getX());
3350
+
3351
+				// new position and new width for the "while"
3352
+				$w-= $str[1];
3353
+				$y = $this->pdf->getY();
3354
+				$x = $this->pdf->getX();
3355
+				$dy = $this->_getElementY($lh);
3356
+
3357
+				// if we have again words to write
3358
+				if (count($words)) {
3359
+					// remove the space at the end
3360
+					if ($add) $w-= $space;
3361
+
3362
+					// if we don't add any word, and if the first word is empty => useless space to skip
3363
+					if (!$add && $words[0][0]==='') {
3364
+						array_shift($words);
3365
+					}
3366
+
3367
+					// if it is just to calculate for one line => adding the number of words
3368
+					if ($this->_isForOneLine) {
3369
+						$this->_maxE+= $i;
3370
+						$this->_maxX = max($this->_maxX, $maxX);
3371
+						return null;
3372
+					}
3373
+
3374
+					// automatic line break
3375
+					$this->_tag_open_BR(array('style' => ''), $currPos);
3376
+
3377
+					// new position
3378
+					$y = $this->pdf->getY();
3379
+					$x = $this->pdf->getX();
3380
+					$dy = $this->_getElementY($lh);
3381
+
3382
+					// if the next line does  not fit on the page => new page
3383
+					if ($y + $h>=$this->pdf->getH() - $this->pdf->getbMargin()) {
3384
+						if (!$this->_isInOverflow && !$this->_isInFooter) {
3385
+							$this->_setNewPage(null, '', null, $currPos);
3386
+							$y = $this->pdf->getY();
3387
+							$x = $this->pdf->getX();
3388
+							$dy = $this->_getElementY($lh);
3389
+						}
3390
+					}
3391
+
3392
+					// if more than 10000 line => error
3393
+					$nb++;
3394
+					if ($nb>10000) {
3395
+						$txt = ''; foreach ($words as $k => $word) $txt.= ($k ? ' ' : '').$word[0];
3396
+						throw new HTML2PDF_exception(2, array($txt, $right-$left, $w));
3397
+					}
3398
+
3399
+					// new margins for the new line
3400
+					list($left, $right) = $this->_getMargins($y);
3401
+				}
3402
+			}
3403
+
3404
+			// if we have words after automatic cut, it is because they fit on the line => we write the text
3405
+			if (count($words)) {
3406
+				$txt = ''; foreach ($words as $k => $word) $txt.= ($k ? ' ' : '').$word[0];
3407
+				$w+= $this->pdf->getWordSpacing()*(count($words));
3408
+				$this->pdf->setXY($this->pdf->getX(), $y+$dh+$dy);
3409
+				$this->pdf->Cell(($align=='L' ? $w : $this->parsingCss->value['width']), $h, $txt, 0, 0, $align, $fill, $this->_isInLink);
3410
+				$this->pdf->setXY($this->pdf->getX(), $y);
3411
+				$this->_maxH = max($this->_maxH, $lh);
3412
+				$this->_maxE+= count($words);
3413
+			}
3414
+
3415
+			$maxX = max($maxX, $this->pdf->getX());
3416
+			$maxY = $this->pdf->getY()+$h;
3417
+
3418
+			$this->_maxX = max($this->_maxX, $maxX);
3419
+			$this->_maxY = max($this->_maxY, $maxY);
3420
+
3421
+			return true;
3422
+		}
3423
+
3424
+		/**
3425
+		 * tag : BR
3426
+		 * mode : OPEN
3427
+		 *
3428
+		 * @param  array   $param
3429
+		 * @param  integer $curr real position in the html parseur (if break line in the write of a text)
3430
+		 * @return boolean
3431
+		 */
3432
+		protected function _tag_open_BR($param, $curr = null)
3433
+		{
3434
+			if ($this->_isForOneLine) return false;
3435
+
3436
+			$h = max($this->_maxH, $this->parsingCss->getLineHeight());
3437
+
3438
+			if ($this->_maxH==0) $this->_maxY = max($this->_maxY, $this->pdf->getY()+$h);
3439
+
3440
+			$this->_makeBreakLine($h, $curr);
3441
+
3442
+			$this->_maxH = 0;
3443
+			$this->_maxE = 0;
3444
+
3445
+			return true;
3446
+		}
3447
+
3448
+		/**
3449
+		 * tag : HR
3450
+		 * mode : OPEN
3451
+		 *
3452
+		 * @param  array $param
3453
+		 * @return boolean
3454
+		 */
3455
+		protected function _tag_open_HR($param)
3456
+		{
3457
+			if ($this->_isForOneLine) return false;
3458
+			$oldAlign = $this->parsingCss->value['text-align'];
3459
+			$this->parsingCss->value['text-align'] = 'left';
3460
+
3461
+			if ($this->_maxH) $this->_tag_open_BR($param);
3462
+
3463
+			$fontSize = $this->parsingCss->value['font-size'];
3464
+			$this->parsingCss->value['font-size']=$fontSize*0.5; $this->_tag_open_BR($param);
3465
+			$this->parsingCss->value['font-size']=0;
3466
+
3467
+			$param['style']['width'] = '100%';
3468
+
3469
+			$this->parsingCss->save();
3470
+			$this->parsingCss->value['height']=$this->parsingCss->ConvertToMM('1mm');
3471
+
3472
+			$this->parsingCss->analyse('hr', $param);
3473
+			$this->parsingCss->setPosition();
3474
+			$this->parsingCss->fontSet();
3475
+
3476
+			$h = $this->parsingCss->value['height'];
3477
+			if ($h)    $h-= $this->parsingCss->value['border']['t']['width']+$this->parsingCss->value['border']['b']['width'];
3478
+			if ($h<=0) $h = $this->parsingCss->value['border']['t']['width']+$this->parsingCss->value['border']['b']['width'];
3479
+
3480
+			$this->_drawRectangle($this->pdf->getX(), $this->pdf->getY(), $this->parsingCss->value['width'], $h, $this->parsingCss->value['border'], 0, 0, $this->parsingCss->value['background']);
3481
+			$this->_maxH = $h;
3482
+
3483
+			$this->parsingCss->load();
3484
+			$this->parsingCss->fontSet();
3485
+
3486
+			$this->_tag_open_BR($param);
3487
+
3488
+			$this->parsingCss->value['font-size']=$fontSize*0.5; $this->_tag_open_BR($param);
3489
+			$this->parsingCss->value['font-size']=$fontSize;
3490
+
3491
+			$this->parsingCss->value['text-align'] = $oldAlign;
3492
+			$this->_setNewPositionForNewLine();
3493
+
3494
+			return true;
3495
+		}
3496
+
3497
+		/**
3498
+		 * tag : B
3499
+		 * mode : OPEN
3500
+		 *
3501
+		 * @param  array $param
3502
+		 * @param  string $other
3503
+		 * @return boolean
3504
+		 */
3505
+		protected function _tag_open_B($param, $other = 'b')
3506
+		{
3507
+			$this->parsingCss->save();
3508
+			$this->parsingCss->value['font-bold'] = true;
3509
+			$this->parsingCss->analyse($other, $param);
3510
+			$this->parsingCss->setPosition();
3511
+			$this->parsingCss->fontSet();
3512
+
3513
+			return true;
3514
+		}
3515
+
3516
+		/**
3517
+		 * tag : STRONG
3518
+		 * mode : OPEN
3519
+		 *
3520
+		 * @param  array $param
3521
+		 * @return boolean
3522
+		 */
3523
+		protected function _tag_open_STRONG($param)
3524
+		{
3525
+			return $this->_tag_open_B($param, 'strong');
3526
+		}
3527
+
3528
+		/**
3529
+		 * tag : B
3530
+		 * mode : CLOSE
3531
+		 *
3532
+		 * @param    array $param
3533
+		 * @return boolean
3534
+		 */
3535
+		protected function _tag_close_B($param)
3536
+		{
3537
+			$this->parsingCss->load();
3538
+			$this->parsingCss->fontSet();
3539
+
3540
+			return true;
3541
+		}
3542
+
3543
+		/**
3544
+		 * tag : STRONG
3545
+		 * mode : CLOSE
3546
+		 *
3547
+		 * @param  array $param
3548
+		 * @return boolean
3549
+		 */
3550
+		protected function _tag_close_STRONG($param)
3551
+		{
3552
+			return $this->_tag_close_B($param);
3553
+		}
3554
+
3555
+		/**
3556
+		 * tag : I
3557
+		 * mode : OPEN
3558
+		 *
3559
+		 * @param  array $param
3560
+		 * @param  string $other
3561
+		 * @return boolean
3562
+		 */
3563
+		protected function _tag_open_I($param, $other = 'i')
3564
+		{
3565
+			$this->parsingCss->save();
3566
+			$this->parsingCss->value['font-italic'] = true;
3567
+			$this->parsingCss->analyse($other, $param);
3568
+			$this->parsingCss->setPosition();
3569
+			$this->parsingCss->fontSet();
3570
+
3571
+			return true;
3572
+		}
3573
+
3574
+		/**
3575
+		 * tag : ADDRESS
3576
+		 * mode : OPEN
3577
+		 *
3578
+		 * @param  array $param
3579
+		 * @return boolean
3580
+		 */
3581
+		protected function _tag_open_ADDRESS($param)
3582
+		{
3583
+			return $this->_tag_open_I($param, 'address');
3584
+		}
3585
+
3586
+		/**
3587
+		 * tag : CITE
3588
+		 * mode : OPEN
3589
+		 *
3590
+		 * @param  array $param
3591
+		 * @return boolean
3592
+		 */
3593
+		protected function _tag_open_CITE($param)
3594
+		{
3595
+			return $this->_tag_open_I($param, 'cite');
3596
+		}
3597
+
3598
+		/**
3599
+		 * tag : EM
3600
+		 * mode : OPEN
3601
+		 *
3602
+		 * @param  array $param
3603
+		 * @return boolean
3604
+		 */
3605
+		protected function _tag_open_EM($param)
3606
+		{
3607
+			return $this->_tag_open_I($param, 'em');
3608
+		}
3609
+
3610
+		/**
3611
+		 * tag : SAMP
3612
+		 * mode : OPEN
3613
+		 *
3614
+		 * @param  array $param
3615
+		 * @return boolean
3616
+		 */
3617
+		protected function _tag_open_SAMP($param)
3618
+		{
3619
+			return $this->_tag_open_I($param, 'samp');
3620
+		}
3621
+
3622
+		/**
3623
+		 * tag : I
3624
+		 * mode : CLOSE
3625
+		 *
3626
+		 * @param  array $param
3627
+		 * @return boolean
3628
+		 */
3629
+		protected function _tag_close_I($param)
3630
+		{
3631
+			$this->parsingCss->load();
3632
+			$this->parsingCss->fontSet();
3633
+
3634
+			return true;
3635
+		}
3636
+
3637
+		/**
3638
+		 * tag : ADDRESS
3639
+		 * mode : CLOSE
3640
+		 *
3641
+		 * @param  array $param
3642
+		 * @return boolean
3643
+		 */
3644
+		protected function _tag_close_ADDRESS($param)
3645
+		{
3646
+			return $this->_tag_close_I($param);
3647
+		}
3648
+
3649
+		/**
3650
+		 * tag : CITE
3651
+		 * mode : CLOSE
3652
+		 *
3653
+		 * @param  array $param
3654
+		 * @return boolean
3655
+		 */
3656
+		protected function _tag_close_CITE($param)
3657
+		{
3658
+			return $this->_tag_close_I($param);
3659
+		}
3660
+
3661
+		/**
3662
+		 * tag : EM
3663
+		 * mode : CLOSE
3664
+		 *
3665
+		 * @param  array $param
3666
+		 * @return boolean
3667
+		 */
3668
+		protected function _tag_close_EM($param)
3669
+		{
3670
+			return $this->_tag_close_I($param);
3671
+		}
3672
+
3673
+		/**
3674
+		 * tag : SAMP
3675
+		 * mode : CLOSE
3676
+		 *
3677
+		 * @param  array $param
3678
+		 * @return boolean
3679
+		 */
3680
+		protected function _tag_close_SAMP($param)
3681
+		{
3682
+			return $this->_tag_close_I($param);
3683
+		}
3684
+
3685
+		/**
3686
+		 * tag : S
3687
+		 * mode : OPEN
3688
+		 *
3689
+		 * @param  array $param
3690
+		 * @param  string $other
3691
+		 * @return boolean
3692
+		 */
3693
+		protected function _tag_open_S($param, $other = 's')
3694
+		{
3695
+			$this->parsingCss->save();
3696
+			$this->parsingCss->value['font-linethrough'] = true;
3697
+			$this->parsingCss->analyse($other, $param);
3698
+			$this->parsingCss->setPosition();
3699
+			$this->parsingCss->fontSet();
3700
+
3701
+			return true;
3702
+		}
3703
+
3704
+		/**
3705
+		 * tag : DEL
3706
+		 * mode : OPEN
3707
+		 *
3708
+		 * @param  array $param
3709
+		 * @return boolean
3710
+		 */
3711
+		protected function _tag_open_DEL($param)
3712
+		{
3713
+			return $this->_tag_open_S($param, 'del');
3714
+		}
3715
+
3716
+		/**
3717
+		 * tag : S
3718
+		 * mode : CLOSE
3719
+		 *
3720
+		 * @param    array $param
3721
+		 * @return boolean
3722
+		 */
3723
+		protected function _tag_close_S($param)
3724
+		{
3725
+			$this->parsingCss->load();
3726
+			$this->parsingCss->fontSet();
3727
+
3728
+			return true;
3729
+		}
3730
+
3731
+		/**
3732
+		 * tag : DEL
3733
+		 * mode : CLOSE
3734
+		 *
3735
+		 * @param  array $param
3736
+		 * @return boolean
3737
+		 */
3738
+		protected function _tag_close_DEL($param)
3739
+		{
3740
+			return $this->_tag_close_S($param);
3741
+		}
3742
+
3743
+		/**
3744
+		 * tag : U
3745
+		 * mode : OPEN
3746
+		 *
3747
+		 * @param  array $param
3748
+		 * @param  string $other
3749
+		 * @return boolean
3750
+		 */
3751
+		protected function _tag_open_U($param, $other='u')
3752
+		{
3753
+			$this->parsingCss->save();
3754
+			$this->parsingCss->value['font-underline'] = true;
3755
+			$this->parsingCss->analyse($other, $param);
3756
+			$this->parsingCss->setPosition();
3757
+			$this->parsingCss->fontSet();
3758
+
3759
+			return true;
3760
+		}
3761
+
3762
+		/**
3763
+		 * tag : INS
3764
+		 * mode : OPEN
3765
+		 *
3766
+		 * @param  array $param
3767
+		 * @return boolean
3768
+		 */
3769
+		protected function _tag_open_INS($param)
3770
+		{
3771
+			return $this->_tag_open_U($param, 'ins');
3772
+		}
3773
+
3774
+		/**
3775
+		 * tag : U
3776
+		 * mode : CLOSE
3777
+		 *
3778
+		 * @param    array $param
3779
+		 * @return boolean
3780
+		 */
3781
+		protected function _tag_close_U($param)
3782
+		{
3783
+			$this->parsingCss->load();
3784
+			$this->parsingCss->fontSet();
3785
+
3786
+			return true;
3787
+		}
3788
+
3789
+		/**
3790
+		 * tag : INS
3791
+		 * mode : CLOSE
3792
+		 *
3793
+		 * @param  array $param
3794
+		 * @return boolean
3795
+		 */
3796
+		protected function _tag_close_INS($param)
3797
+		{
3798
+			return $this->_tag_close_U($param);
3799
+		}
3800
+
3801
+		/**
3802
+		 * tag : A
3803
+		 * mode : OPEN
3804
+		 *
3805
+		 * @param  array $param
3806
+		 * @return boolean
3807
+		 */
3808
+		protected function _tag_open_A($param)
3809
+		{
3810
+			$this->_isInLink = str_replace('&amp;', '&', isset($param['href']) ? $param['href'] : '');
3811
+
3812
+			if (isset($param['name'])) {
3813
+				$name =     $param['name'];
3814
+				if (!isset($this->_lstAnchor[$name])) $this->_lstAnchor[$name] = array($this->pdf->AddLink(), false);
3815
+
3816
+				if (!$this->_lstAnchor[$name][1]) {
3817
+					$this->_lstAnchor[$name][1] = true;
3818
+					$this->pdf->SetLink($this->_lstAnchor[$name][0], -1, -1);
3819
+				}
3820
+			}
3821
+
3822
+			if (preg_match('/^#([^#]+)$/isU', $this->_isInLink, $match)) {
3823
+				$name = $match[1];
3824
+				if (!isset($this->_lstAnchor[$name])) $this->_lstAnchor[$name] = array($this->pdf->AddLink(), false);
3825
+
3826
+				$this->_isInLink = $this->_lstAnchor[$name][0];
3827
+			}
3828
+
3829
+			$this->parsingCss->save();
3830
+			$this->parsingCss->value['font-underline'] = true;
3831
+			$this->parsingCss->value['color'] = array(20, 20, 250);
3832
+			$this->parsingCss->analyse('a', $param);
3833
+			$this->parsingCss->setPosition();
3834
+			$this->parsingCss->fontSet();
3835
+
3836
+			return true;
3837
+		}
3838
+
3839
+		/**
3840
+		 * tag : A
3841
+		 * mode : CLOSE
3842
+		 *
3843
+		 * @param  array $param
3844
+		 * @return boolean
3845
+		 */
3846
+		protected function _tag_close_A($param)
3847
+		{
3848
+			$this->_isInLink    = '';
3849
+			$this->parsingCss->load();
3850
+			$this->parsingCss->fontSet();
3851
+
3852
+			return true;
3853
+		}
3854
+
3855
+		/**
3856
+		 * tag : H1
3857
+		 * mode : OPEN
3858
+		 *
3859
+		 * @param  array $param
3860
+		 * @param  string $other
3861
+		 * @return boolean
3862
+		 */
3863
+		protected function _tag_open_H1($param, $other = 'h1')
3864
+		{
3865
+			if ($this->_isForOneLine) return false;
3866
+
3867
+			if ($this->_maxH) $this->_tag_open_BR(array());
3868
+			$this->parsingCss->save();
3869
+			$this->parsingCss->value['font-bold'] = true;
3870
+
3871
+			$size = array('h1' => '28px', 'h2' => '24px', 'h3' => '20px', 'h4' => '16px', 'h5' => '12px', 'h6' => '9px');
3872
+			$this->parsingCss->value['margin']['l'] = 0;
3873
+			$this->parsingCss->value['margin']['r'] = 0;
3874
+			$this->parsingCss->value['margin']['t'] = $this->parsingCss->ConvertToMM('16px');
3875
+			$this->parsingCss->value['margin']['b'] = $this->parsingCss->ConvertToMM('16px');
3876
+			$this->parsingCss->value['font-size'] = $this->parsingCss->ConvertToMM($size[$other]);
3877
+
3878
+			$this->parsingCss->analyse($other, $param);
3879
+			$this->parsingCss->setPosition();
3880
+			$this->parsingCss->fontSet();
3881
+			$this->_setNewPositionForNewLine();
3882
+
3883
+			return true;
3884
+		}
3885
+
3886
+		/**
3887
+		 * tag : H2
3888
+		 * mode : OPEN
3889
+		 *
3890
+		 * @param  array $param
3891
+		 * @return boolean
3892
+		 */
3893
+		protected function _tag_open_H2($param)
3894
+		{
3895
+			return $this->_tag_open_H1($param, 'h2');
3896
+		}
3897
+
3898
+		/**
3899
+		 * tag : H3
3900
+		 * mode : OPEN
3901
+		 *
3902
+		 * @param  array $param
3903
+		 * @return boolean
3904
+		 */
3905
+		protected function _tag_open_H3($param)
3906
+		{
3907
+			return $this->_tag_open_H1($param, 'h3');
3908
+		}
3909
+
3910
+		/**
3911
+		 * tag : H4
3912
+		 * mode : OPEN
3913
+		 *
3914
+		 * @param  array $param
3915
+		 * @return boolean
3916
+		 */
3917
+		protected function _tag_open_H4($param)
3918
+		{
3919
+			return $this->_tag_open_H1($param, 'h4');
3920
+		}
3921
+
3922
+		/**
3923
+		 * tag : H5
3924
+		 * mode : OPEN
3925
+		 *
3926
+		 * @param  array $param
3927
+		 * @return boolean
3928
+		 */
3929
+		protected function _tag_open_H5($param)
3930
+		{
3931
+			return $this->_tag_open_H1($param, 'h5');
3932
+		}
3933
+
3934
+		/**
3935
+		 * tag : H6
3936
+		 * mode : OPEN
3937
+		 *
3938
+		 * @param  array $param
3939
+		 * @return boolean
3940
+		 */
3941
+		protected function _tag_open_H6($param)
3942
+		{
3943
+			return $this->_tag_open_H1($param, 'h6');
3944
+		}
3945
+
3946
+		/**
3947
+		 * tag : H1
3948
+		 * mode : CLOSE
3949
+		 *
3950
+		 * @param  array $param
3951
+		 * @return boolean
3952
+		 */
3953
+		protected function _tag_close_H1($param)
3954
+		{
3955
+			if ($this->_isForOneLine) return false;
3956
+
3957
+			$this->_maxH+= $this->parsingCss->value['margin']['b'];
3958
+			$h = max($this->_maxH, $this->parsingCss->getLineHeight());
3959
+
3960
+			$this->parsingCss->load();
3961
+			$this->parsingCss->fontSet();
3962
+
3963
+			$this->_makeBreakLine($h);
3964
+			$this->_maxH = 0;
3965
+
3966
+			$this->_maxY = max($this->_maxY, $this->pdf->getY());
3967
+
3968
+			return true;
3969
+		}
3970
+
3971
+		/**
3972
+		 * tag : H2
3973
+		 * mode : CLOSE
3974
+		 *
3975
+		 * @param  array $param
3976
+		 * @return boolean
3977
+		 */
3978
+		protected function _tag_close_H2($param)
3979
+		{
3980
+			return $this->_tag_close_H1($param);
3981
+		}
3982
+
3983
+		/**
3984
+		 * tag : H3
3985
+		 * mode : CLOSE
3986
+		 *
3987
+		 * @param  array $param
3988
+		 * @return boolean
3989
+		 */
3990
+		protected function _tag_close_H3($param)
3991
+		{
3992
+			return $this->_tag_close_H1($param);
3993
+		}
3994
+
3995
+		/**
3996
+		 * tag : H4
3997
+		 * mode : CLOSE
3998
+		 *
3999
+		 * @param  array $param
4000
+		 * @return boolean
4001
+		 */
4002
+		protected function _tag_close_H4($param)
4003
+		{
4004
+			return $this->_tag_close_H1($param);
4005
+		}
4006
+
4007
+		/**
4008
+		 * tag : H5
4009
+		 * mode : CLOSE
4010
+		 *
4011
+		 * @param  array $param
4012
+		 * @return boolean
4013
+		 */
4014
+		protected function _tag_close_H5($param)
4015
+		{
4016
+			return $this->_tag_close_H1($param);
4017
+		}
4018
+
4019
+		/**
4020
+		 * tag : H6
4021
+		 * mode : CLOSE
4022
+		 *
4023
+		 * @param  array $param
4024
+		 * @return boolean
4025
+		 */
4026
+		protected function _tag_close_H6($param)
4027
+		{
4028
+			return $this->_tag_close_H1($param);
4029
+		}
4030
+
4031
+		/**
4032
+		 * tag : SPAN
4033
+		 * mode : OPEN
4034
+		 *
4035
+		 * @param  array $param
4036
+		 * @param  string $other
4037
+		 * @return boolean
4038
+		 */
4039
+		protected function _tag_open_SPAN($param, $other = 'span')
4040
+		{
4041
+			$this->parsingCss->save();
4042
+			$this->parsingCss->analyse($other, $param);
4043
+			$this->parsingCss->setPosition();
4044
+			$this->parsingCss->fontSet();
4045
+
4046
+			return true;
4047
+		}
4048
+
4049
+		/**
4050
+		 * tag : FONT
4051
+		 * mode : OPEN
4052
+		 *
4053
+		 * @param  array $param
4054
+		 * @return boolean
4055
+		 */
4056
+		protected function _tag_open_FONT($param)
4057
+		{
4058
+			return $this->_tag_open_SPAN($param, 'font');
4059
+		}
4060
+
4061
+		/**
4062
+		 * tag : LABEL
4063
+		 * mode : OPEN
4064
+		 *
4065
+		 * @param  array $param
4066
+		 * @return boolean
4067
+		 */
4068
+		protected function _tag_open_LABEL($param)
4069
+		{
4070
+			return $this->_tag_open_SPAN($param, 'label');
4071
+		}
4072
+
4073
+		/**
4074
+		 * tag : SPAN
4075
+		 * mode : CLOSE
4076
+		 *
4077
+		 * @param  array $param
4078
+		 * @return boolean
4079
+		 */
4080
+		protected function _tag_close_SPAN($param)
4081
+		{
4082
+			$this->parsingCss->restorePosition();
4083
+			$this->parsingCss->load();
4084
+			$this->parsingCss->fontSet();
4085
+
4086
+			return true;
4087
+		}
4088
+
4089
+		/**
4090
+		 * tag : FONT
4091
+		 * mode : CLOSE
4092
+		 *
4093
+		 * @param  array $param
4094
+		 * @return boolean
4095
+		 */
4096
+		protected function _tag_close_FONT($param)
4097
+		{
4098
+			return $this->_tag_close_SPAN($param);
4099
+		}
4100
+
4101
+		/**
4102
+		 * tag : LABEL
4103
+		 * mode : CLOSE
4104
+		 *
4105
+		 * @param  array $param
4106
+		 * @return boolean
4107
+		 */
4108
+		protected function _tag_close_LABEL($param)
4109
+		{
4110
+			return $this->_tag_close_SPAN($param);
4111
+		}
4112
+
4113
+		/**
4114
+		 * tag : P
4115
+		 * mode : OPEN
4116
+		 *
4117
+		 * @param    array $param
4118
+		 * @return boolean
4119
+		 */
4120
+		protected function _tag_open_P($param)
4121
+		{
4122
+			if ($this->_isForOneLine) return false;
4123
+
4124
+			if (!in_array($this->_previousCall, array('_tag_close_P', '_tag_close_UL'))) {
4125
+				if ($this->_maxH) $this->_tag_open_BR(array());
4126
+			}
4127
+
4128
+			$this->parsingCss->save();
4129
+			$this->parsingCss->analyse('p', $param);
4130
+			$this->parsingCss->setPosition();
4131
+			$this->parsingCss->fontSet();
4132
+
4133
+			 // cancel the effects of the setPosition
4134
+			$this->pdf->setXY($this->pdf->getX()-$this->parsingCss->value['margin']['l'], $this->pdf->getY()-$this->parsingCss->value['margin']['t']);
4135
+
4136
+			list($mL, $mR) = $this->_getMargins($this->pdf->getY());
4137
+			$mR = $this->pdf->getW()-$mR;
4138
+			$mL+= $this->parsingCss->value['margin']['l']+$this->parsingCss->value['padding']['l'];
4139
+			$mR+= $this->parsingCss->value['margin']['r']+$this->parsingCss->value['padding']['r'];
4140
+			$this->_saveMargin($mL, 0, $mR);
4141
+
4142
+			if ($this->parsingCss->value['text-indent']>0) {
4143
+				$y = $this->pdf->getY()+$this->parsingCss->value['margin']['t']+$this->parsingCss->value['padding']['t'];
4144
+				$this->_pageMarges[floor($y*100)] = array($mL+$this->parsingCss->value['text-indent'], $this->pdf->getW()-$mR);
4145
+				$y+= $this->parsingCss->getLineHeight()*0.1;
4146
+				$this->_pageMarges[floor($y*100)] = array($mL, $this->pdf->getW()-$mR);
4147
+			}
4148
+			$this->_makeBreakLine($this->parsingCss->value['margin']['t']+$this->parsingCss->value['padding']['t']);
4149
+			$this->_isInParagraph = array($mL, $mR);
4150
+			return true;
4151
+		}
4152
+
4153
+		/**
4154
+		 * tag : P
4155
+		 * mode : CLOSE
4156
+		 *
4157
+		 * @param  array $param
4158
+		 * @return boolean
4159
+		 */
4160
+		protected function _tag_close_P($param)
4161
+		{
4162
+			if ($this->_isForOneLine) return false;
4163
+
4164
+			if ($this->_maxH) $this->_tag_open_BR(array());
4165
+			$this->_isInParagraph = false;
4166
+			$this->_loadMargin();
4167
+			$h = $this->parsingCss->value['margin']['b']+$this->parsingCss->value['padding']['b'];
4168
+
4169
+			$this->parsingCss->load();
4170
+			$this->parsingCss->fontSet();
4171
+			$this->_makeBreakLine($h);
4172
+
4173
+			return true;
4174
+		}
4175
+
4176
+		/**
4177
+		 * tag : PRE
4178
+		 * mode : OPEN
4179
+		 *
4180
+		 * @param  array $param
4181
+		 * @param  string $other
4182
+		 * @return boolean
4183
+		 */
4184
+		protected function _tag_open_PRE($param, $other = 'pre')
4185
+		{
4186
+			if ($other=='pre' && $this->_maxH) $this->_tag_open_BR(array());
4187
+
4188
+			$this->parsingCss->save();
4189
+			$this->parsingCss->value['font-family'] = 'courier';
4190
+			$this->parsingCss->analyse($other, $param);
4191
+			$this->parsingCss->setPosition();
4192
+			$this->parsingCss->fontSet();
4193
+
4194
+			if ($other=='pre') return $this->_tag_open_DIV($param, $other);
4195
+
4196
+			return true;
4197
+		}
4198
+
4199
+		/**
4200
+		 * tag : CODE
4201
+		 * mode : OPEN
4202
+		 *
4203
+		 * @param  array $param
4204
+		 * @param  string $other
4205
+		 * @return boolean
4206
+		 */
4207
+		protected function _tag_open_CODE($param)
4208
+		{
4209
+			return $this->_tag_open_PRE($param, 'code');
4210
+		}
4211
+
4212
+		/**
4213
+		 * tag : PRE
4214
+		 * mode : CLOSE
4215
+		 *
4216
+		 * @param  array $param
4217
+		 * @param  string $other
4218
+		 * @return boolean
4219
+		 */
4220
+		protected function _tag_close_PRE($param, $other = 'pre')
4221
+		{
4222
+			if ($other=='pre') {
4223
+				if ($this->_isForOneLine) return false;
4224
+
4225
+				$this->_tag_close_DIV($param, $other);
4226
+				$this->_tag_open_BR(array());
4227
+			}
4228
+			$this->parsingCss->load();
4229
+			$this->parsingCss->fontSet();
4230
+
4231
+			return true;
4232
+		}
4233
+
4234
+		/**
4235
+		 * tag : CODE
4236
+		 * mode : CLOSE
4237
+		 *
4238
+		 * @param  array $param
4239
+		 * @return boolean
4240
+		 */
4241
+		protected function _tag_close_CODE($param)
4242
+		{
4243
+			return $this->_tag_close_PRE($param, 'code');
4244
+		}
4245
+
4246
+		/**
4247
+		 * tag : BIG
4248
+		 * mode : OPEN
4249
+		 *
4250
+		 * @param    array $param
4251
+		 * @return boolean
4252
+		 */
4253
+		protected function _tag_open_BIG($param)
4254
+		{
4255
+			$this->parsingCss->save();
4256
+			$this->parsingCss->value['mini-decal']-= $this->parsingCss->value['mini-size']*0.12;
4257
+			$this->parsingCss->value['mini-size'] *= 1.2;
4258
+			$this->parsingCss->analyse('big', $param);
4259
+			$this->parsingCss->setPosition();
4260
+			$this->parsingCss->fontSet();
4261
+			return true;
4262
+		}
4263
+
4264
+		/**
4265
+		 * tag : BIG
4266
+		 * mode : CLOSE
4267
+		 *
4268
+		 * @param    array $param
4269
+		 * @return boolean
4270
+		 */
4271
+		protected function _tag_close_BIG($param)
4272
+		{
4273
+			$this->parsingCss->load();
4274
+			$this->parsingCss->fontSet();
4275
+
4276
+			return true;
4277
+		}
4278
+
4279
+		/**
4280
+		 * tag : SMALL
4281
+		 * mode : OPEN
4282
+		 *
4283
+		 * @param    array $param
4284
+		 * @return boolean
4285
+		 */
4286
+		protected function _tag_open_SMALL($param)
4287
+		{
4288
+			$this->parsingCss->save();
4289
+			$this->parsingCss->value['mini-decal']+= $this->parsingCss->value['mini-size']*0.05;
4290
+			$this->parsingCss->value['mini-size'] *= 0.82;
4291
+			$this->parsingCss->analyse('small', $param);
4292
+			$this->parsingCss->setPosition();
4293
+			$this->parsingCss->fontSet();
4294
+			return true;
4295
+		}
4296
+
4297
+		/**
4298
+		 * tag : SMALL
4299
+		 * mode : CLOSE
4300
+		 *
4301
+		 * @param    array $param
4302
+		 * @return boolean
4303
+		 */
4304
+		protected function _tag_close_SMALL($param)
4305
+		{
4306
+			$this->parsingCss->load();
4307
+			$this->parsingCss->fontSet();
4308
+
4309
+			return true;
4310
+		}
4311
+
4312
+		/**
4313
+		 * tag : SUP
4314
+		 * mode : OPEN
4315
+		 *
4316
+		 * @param    array $param
4317
+		 * @return boolean
4318
+		 */
4319
+		protected function _tag_open_SUP($param)
4320
+		{
4321
+			$this->parsingCss->save();
4322
+			$this->parsingCss->value['mini-decal']-= $this->parsingCss->value['mini-size']*0.15;
4323
+			$this->parsingCss->value['mini-size'] *= 0.75;
4324
+			$this->parsingCss->analyse('sup', $param);
4325
+			$this->parsingCss->setPosition();
4326
+			$this->parsingCss->fontSet();
4327
+
4328
+			return true;
4329
+		}
4330
+
4331
+		/**
4332
+		 * tag : SUP
4333
+		 * mode : CLOSE
4334
+		 *
4335
+		 * @param    array $param
4336
+		 * @return boolean
4337
+		 */
4338
+		protected function _tag_close_SUP($param)
4339
+		{
4340
+			$this->parsingCss->load();
4341
+			$this->parsingCss->fontSet();
4342
+
4343
+			return true;
4344
+		}
4345
+
4346
+		/**
4347
+		 * tag : SUB
4348
+		 * mode : OPEN
4349
+		 *
4350
+		 * @param    array $param
4351
+		 * @return boolean
4352
+		 */
4353
+		protected function _tag_open_SUB($param)
4354
+		{
4355
+			$this->parsingCss->save();
4356
+			$this->parsingCss->value['mini-decal']+= $this->parsingCss->value['mini-size']*0.15;
4357
+			$this->parsingCss->value['mini-size'] *= 0.75;
4358
+			$this->parsingCss->analyse('sub', $param);
4359
+			$this->parsingCss->setPosition();
4360
+			$this->parsingCss->fontSet();
4361
+			return true;
4362
+		}
4363
+
4364
+		/**
4365
+		 * tag : SUB
4366
+		 * mode : CLOSE
4367
+		 *
4368
+		 * @param    array $param
4369
+		 * @return boolean
4370
+		 */
4371
+		protected function _tag_close_SUB($param)
4372
+		{
4373
+			$this->parsingCss->load();
4374
+			$this->parsingCss->fontSet();
4375
+
4376
+			return true;
4377
+		}
4378
+
4379
+		/**
4380
+		 * tag : UL
4381
+		 * mode : OPEN
4382
+		 *
4383
+		 * @param  array $param
4384
+		 * @param  string $other
4385
+		 * @return boolean
4386
+		 */
4387
+		protected function _tag_open_UL($param, $other = 'ul')
4388
+		{
4389
+			if ($this->_isForOneLine) return false;
4390
+
4391
+			if (!in_array($this->_previousCall, array('_tag_close_P', '_tag_close_UL'))) {
4392
+				if ($this->_maxH) $this->_tag_open_BR(array());
4393
+				if (!count($this->_defList)) $this->_tag_open_BR(array());
4394
+			}
4395
+
4396
+			if (!isset($param['style']['width'])) $param['allwidth'] = true;
4397
+			$param['cellspacing'] = 0;
4398
+
4399
+			// a list is like a table
4400
+			$this->_tag_open_TABLE($param, $other);
4401
+
4402
+			// add a level of list
4403
+			$this->_listeAddLevel($other, $this->parsingCss->value['list-style-type'], $this->parsingCss->value['list-style-image']);
4404
+
4405
+			return true;
4406
+		}
4407
+
4408
+		/**
4409
+		 * tag : OL
4410
+		 * mode : OPEN
4411
+		 *
4412
+		 * @param  array $param
4413
+		 * @return boolean
4414
+		 */
4415
+		protected function _tag_open_OL($param)
4416
+		{
4417
+			return $this->_tag_open_UL($param, 'ol');
4418
+		}
4419
+
4420
+		/**
4421
+		 * tag : UL
4422
+		 * mode : CLOSE
4423
+		 *
4424
+		 * @param  array $param
4425
+		 * @return boolean
4426
+		 */
4427
+		protected function _tag_close_UL($param)
4428
+		{
4429
+			if ($this->_isForOneLine) return false;
4430
+
4431
+			$this->_tag_close_TABLE($param);
4432
+
4433
+			$this->_listeDelLevel();
4434
+
4435
+			if (!$this->_subPart) {
4436
+				if (!count($this->_defList)) $this->_tag_open_BR(array());
4437
+			}
4438
+
4439
+			return true;
4440
+		}
4441
+
4442
+		/**
4443
+		 * tag : OL
4444
+		 * mode : CLOSE
4445
+		 *
4446
+		 * @param  array $param
4447
+		 * @return boolean
4448
+		 */
4449
+		protected function _tag_close_OL($param)
4450
+		{
4451
+			return $this->_tag_close_UL($param);
4452
+		}
4453
+
4454
+		/**
4455
+		 * tag : LI
4456
+		 * mode : OPEN
4457
+		 *
4458
+		 * @param  array $param
4459
+		 * @return boolean
4460
+		 */
4461
+		protected function _tag_open_LI($param)
4462
+		{
4463
+			if ($this->_isForOneLine) return false;
4464
+
4465
+			$this->_listeAddLi();
4466
+
4467
+			if (!isset($param['style']['width'])) $param['style']['width'] = '100%';
4468
+
4469
+			$paramPUCE = $param;
4470
+
4471
+			$inf = $this->_listeGetLi();
4472
+			if ($inf[0]) {
4473
+				$paramPUCE['style']['font-family']     = $inf[0];
4474
+				$paramPUCE['style']['text-align']      = 'li_right';
4475
+				$paramPUCE['style']['vertical-align']  = 'top';
4476
+				$paramPUCE['style']['width']           = $this->_listeGetWidth();
4477
+				$paramPUCE['style']['padding-right']   = $this->_listeGetPadding();
4478
+				$paramPUCE['txt'] = $inf[2];
4479
+			} else {
4480
+				$paramPUCE['style']['text-align']      = 'li_right';
4481
+				$paramPUCE['style']['vertical-align']  = 'top';
4482
+				$paramPUCE['style']['width']           = $this->_listeGetWidth();
4483
+				$paramPUCE['style']['padding-right']   = $this->_listeGetPadding();
4484
+				$paramPUCE['src'] = $inf[2];
4485
+				$paramPUCE['sub_li'] = true;
4486
+			}
4487
+
4488
+			$this->_tag_open_TR($param, 'li');
4489
+
4490
+			$this->parsingCss->save();
4491
+
4492
+			// if small LI
4493
+			if ($inf[1]) {
4494
+				$this->parsingCss->value['mini-decal']+= $this->parsingCss->value['mini-size']*0.045;
4495
+				$this->parsingCss->value['mini-size'] *= 0.75;
4496
+			}
4497
+
4498
+			// if we are in a sub html => prepare. Else : display
4499
+			if ($this->_subPart) {
4500
+				// TD for the puce
4501
+				$tmpPos = $this->_tempPos;
4502
+				$tmpLst1 = $this->parsingHtml->code[$tmpPos+1];
4503
+				$tmpLst2 = $this->parsingHtml->code[$tmpPos+2];
4504
+				$this->parsingHtml->code[$tmpPos+1] = array();
4505
+				$this->parsingHtml->code[$tmpPos+1]['name']    = (isset($paramPUCE['src'])) ? 'img' : 'write';
4506
+				$this->parsingHtml->code[$tmpPos+1]['param']    = $paramPUCE; unset($this->parsingHtml->code[$tmpPos+1]['param']['style']['width']);
4507
+				$this->parsingHtml->code[$tmpPos+1]['close']    = 0;
4508
+				$this->parsingHtml->code[$tmpPos+2] = array();
4509
+				$this->parsingHtml->code[$tmpPos+2]['name']    = 'li';
4510
+				$this->parsingHtml->code[$tmpPos+2]['param']    = $paramPUCE;
4511
+				$this->parsingHtml->code[$tmpPos+2]['close']    = 1;
4512
+				$this->_tag_open_TD($paramPUCE, 'li_sub');
4513
+				$this->_tag_close_TD($param);
4514
+				$this->_tempPos = $tmpPos;
4515
+				$this->parsingHtml->code[$tmpPos+1] = $tmpLst1;
4516
+				$this->parsingHtml->code[$tmpPos+2] = $tmpLst2;
4517
+			} else {
4518
+				// TD for the puce
4519
+				$this->_tag_open_TD($paramPUCE, 'li_sub');
4520
+				unset($paramPUCE['style']['width']);
4521
+				if (isset($paramPUCE['src']))    $this->_tag_open_IMG($paramPUCE);
4522
+				else                            $this->_tag_open_WRITE($paramPUCE);
4523
+				$this->_tag_close_TD($paramPUCE);
4524
+			}
4525
+			$this->parsingCss->load();
4526
+
4527
+
4528
+			// TD for the content
4529
+			$this->_tag_open_TD($param, 'li');
4530
+
4531
+			return true;
4532
+		}
4533
+
4534
+		/**
4535
+		 * tag : LI
4536
+		 * mode : CLOSE
4537
+		 *
4538
+		 * @param  array $param
4539
+		 * @return boolean
4540
+		 */
4541
+		protected function _tag_close_LI($param)
4542
+		{
4543
+			if ($this->_isForOneLine) return false;
4544
+
4545
+			$this->_tag_close_TD($param);
4546
+
4547
+			$this->_tag_close_TR($param);
4548
+
4549
+			return true;
4550
+		}
4551
+
4552
+		/**
4553
+		 * tag : TBODY
4554
+		 * mode : OPEN
4555
+		 *
4556
+		 * @param  array $param
4557
+		 * @return boolean
4558
+		 */
4559
+		protected function _tag_open_TBODY($param)
4560
+		{
4561
+			if ($this->_isForOneLine) return false;
4562
+
4563
+			$this->parsingCss->save();
4564
+			$this->parsingCss->analyse('tbody', $param);
4565
+			$this->parsingCss->setPosition();
4566
+			$this->parsingCss->fontSet();
4567
+
4568
+			return true;
4569
+		}
4570
+
4571
+		/**
4572
+		 * tag : TBODY
4573
+		 * mode : CLOSE
4574
+		 *
4575
+		 * @param  array $param
4576
+		 * @return boolean
4577
+		 */
4578
+		protected function _tag_close_TBODY($param)
4579
+		{
4580
+			if ($this->_isForOneLine) return false;
4581
+
4582
+			$this->parsingCss->load();
4583
+			$this->parsingCss->fontSet();
4584
+
4585
+			return true;
4586
+		}
4587
+
4588
+		/**
4589
+		 * tag : THEAD
4590
+		 * mode : OPEN
4591
+		 *
4592
+		 * @param  array $param
4593
+		 * @return boolean
4594
+		 */
4595
+		protected function _tag_open_THEAD($param)
4596
+		{
4597
+			if ($this->_isForOneLine) return false;
4598
+
4599
+			$this->parsingCss->save();
4600
+			$this->parsingCss->analyse('thead', $param);
4601
+			$this->parsingCss->setPosition();
4602
+			$this->parsingCss->fontSet();
4603
+
4604
+			// if we are in a sub part, save the number of the first TR in the thead
4605
+			if ($this->_subPart) {
4606
+				HTML2PDF::$_tables[$param['num']]['thead']['tr'][0] = HTML2PDF::$_tables[$param['num']]['tr_curr'];
4607
+				HTML2PDF::$_tables[$param['num']]['thead']['code'] = array();
4608
+				for ($pos=$this->_tempPos; $pos<count($this->parsingHtml->code); $pos++) {
4609
+					$action = $this->parsingHtml->code[$pos];
4610
+					if (strtolower($action['name'])=='thead') $action['name'] = 'thead_sub';
4611
+					HTML2PDF::$_tables[$param['num']]['thead']['code'][] = $action;
4612
+					if (strtolower($action['name'])=='thead_sub' && $action['close']) break;
4613
+				}
4614
+			} else {
4615
+				$level = $this->parsingHtml->getLevel($this->_parsePos);
4616
+				$this->_parsePos+= count($level);
4617
+				HTML2PDF::$_tables[$param['num']]['tr_curr']+= count(HTML2PDF::$_tables[$param['num']]['thead']['tr']);
4618
+			}
4619
+
4620
+			return true;
4621
+		}
4622
+
4623
+		/**
4624
+		 * tag : THEAD
4625
+		 * mode : CLOSE
4626
+		 *
4627
+		 * @param  array $param
4628
+		 * @return boolean
4629
+		 */
4630
+		protected function _tag_close_THEAD($param)
4631
+		{
4632
+			if ($this->_isForOneLine) return false;
4633
+
4634
+			$this->parsingCss->load();
4635
+			$this->parsingCss->fontSet();
4636
+
4637
+			// if we are in a sub HTM, construct the list of the TR in the thead
4638
+			if ($this->_subPart) {
4639
+				$min = HTML2PDF::$_tables[$param['num']]['thead']['tr'][0];
4640
+				$max = HTML2PDF::$_tables[$param['num']]['tr_curr']-1;
4641
+				HTML2PDF::$_tables[$param['num']]['thead']['tr'] = range($min, $max);
4642
+			}
4643
+
4644
+			return true;
4645
+		}
4646
+
4647
+		/**
4648
+		 * tag : TFOOT
4649
+		 * mode : OPEN
4650
+		 *
4651
+		 * @param  array $param
4652
+		 * @return boolean
4653
+		 */
4654
+		protected function _tag_open_TFOOT($param)
4655
+		{
4656
+			if ($this->_isForOneLine) return false;
4657
+
4658
+			$this->parsingCss->save();
4659
+			$this->parsingCss->analyse('tfoot', $param);
4660
+			$this->parsingCss->setPosition();
4661
+			$this->parsingCss->fontSet();
4662
+
4663
+			// if we are in a sub part, save the number of the first TR in the tfoot
4664
+			if ($this->_subPart) {
4665
+				HTML2PDF::$_tables[$param['num']]['tfoot']['tr'][0] = HTML2PDF::$_tables[$param['num']]['tr_curr'];
4666
+				HTML2PDF::$_tables[$param['num']]['tfoot']['code'] = array();
4667
+				for ($pos=$this->_tempPos; $pos<count($this->parsingHtml->code); $pos++) {
4668
+					$action = $this->parsingHtml->code[$pos];
4669
+					if (strtolower($action['name'])=='tfoot') $action['name'] = 'tfoot_sub';
4670
+					HTML2PDF::$_tables[$param['num']]['tfoot']['code'][] = $action;
4671
+					if (strtolower($action['name'])=='tfoot_sub' && $action['close']) break;
4672
+				}
4673
+			} else {
4674
+				$level = $this->parsingHtml->getLevel($this->_parsePos);
4675
+				$this->_parsePos+= count($level);
4676
+				HTML2PDF::$_tables[$param['num']]['tr_curr']+= count(HTML2PDF::$_tables[$param['num']]['tfoot']['tr']);
4677
+			}
4678
+
4679
+			return true;
4680
+		}
4681
+
4682
+		/**
4683
+		 * tag : TFOOT
4684
+		 * mode : CLOSE
4685
+		 *
4686
+		 * @param  array $param
4687
+		 * @return boolean
4688
+		 */
4689
+		protected function _tag_close_TFOOT($param)
4690
+		{
4691
+			if ($this->_isForOneLine) return false;
4692
+
4693
+			$this->parsingCss->load();
4694
+			$this->parsingCss->fontSet();
4695
+
4696
+			// if we are in a sub HTM, construct the list of the TR in the tfoot
4697
+			if ($this->_subPart) {
4698
+				$min = HTML2PDF::$_tables[$param['num']]['tfoot']['tr'][0];
4699
+				$max = HTML2PDF::$_tables[$param['num']]['tr_curr']-1;
4700
+				HTML2PDF::$_tables[$param['num']]['tfoot']['tr'] = range($min, $max);
4701
+			}
4702
+
4703
+			return true;
4704
+		}
4705
+
4706
+		/**
4707
+		 * It is not a real TAG, does not use it !
4708
+		 *
4709
+		 * @param  array $param
4710
+		 * @return boolean
4711
+		 */
4712
+		protected function _tag_open_THEAD_SUB($param)
4713
+		{
4714
+			if ($this->_isForOneLine) return false;
4715
+
4716
+			$this->parsingCss->save();
4717
+			$this->parsingCss->analyse('thead', $param);
4718
+			$this->parsingCss->setPosition();
4719
+			$this->parsingCss->fontSet();
4720
+
4721
+			return true;
4722
+		}
4723
+
4724
+		/**
4725
+		 * It is not a real TAG, does not use it !
4726
+		 *
4727
+		 * @param  array $param
4728
+		 * @return boolean
4729
+		 */
4730
+		protected function _tag_close_THEAD_SUB($param)
4731
+		{
4732
+			if ($this->_isForOneLine) return false;
4733
+
4734
+			$this->parsingCss->load();
4735
+			$this->parsingCss->fontSet();
4736
+
4737
+			return true;
4738
+		}
4739
+
4740
+		/**
4741
+		 * It is not a real TAG, does not use it !
4742
+		 *
4743
+		 * @param    array $param
4744
+		 * @return boolean
4745
+		 */
4746
+		protected function _tag_open_TFOOT_SUB($param)
4747
+		{
4748
+			if ($this->_isForOneLine) return false;
4749
+
4750
+			$this->parsingCss->save();
4751
+			$this->parsingCss->analyse('tfoot', $param);
4752
+			$this->parsingCss->setPosition();
4753
+			$this->parsingCss->fontSet();
4754
+
4755
+			return true;
4756
+		}
4757
+
4758
+		/**
4759
+		 * It is not a real TAG, does not use it !
4760
+		 *
4761
+		 * @param  array $param
4762
+		 * @return boolean
4763
+		 */
4764
+		protected function _tag_close_TFOOT_SUB($param)
4765
+		{
4766
+			if ($this->_isForOneLine) return false;
4767
+
4768
+			$this->parsingCss->load();
4769
+			$this->parsingCss->fontSet();
4770
+
4771
+			return true;
4772
+		}
4773
+
4774
+		/**
4775
+		 * tag : FORM
4776
+		 * mode : OPEN
4777
+		 *
4778
+		 * @param  array $param
4779
+		 * @return boolean
4780
+		 */
4781
+		protected function _tag_open_FORM($param)
4782
+		{
4783
+			$this->parsingCss->save();
4784
+			$this->parsingCss->analyse('form', $param);
4785
+			$this->parsingCss->setPosition();
4786
+			$this->parsingCss->fontSet();
4787
+
4788
+			$this->pdf->setFormDefaultProp(
4789
+				array(
4790
+					'lineWidth'=>1,
4791
+					'borderStyle'=>'solid',
4792
+					'fillColor'=>array(220, 220, 255),
4793
+					'strokeColor'=>array(128, 128, 200)
4794
+				)
4795
+			);
4796
+
4797
+			$this->_isInForm = isset($param['action']) ? $param['action'] : '';
4798
+
4799
+			return true;
4800
+		}
4801
+
4802
+		/**
4803
+		 * tag : FORM
4804
+		 * mode : CLOSE
4805
+		 *
4806
+		 * @param  array $param
4807
+		 * @return boolean
4808
+		 */
4809
+		protected function _tag_close_FORM($param)
4810
+		{
4811
+			$this->_isInForm = false;
4812
+			$this->parsingCss->load();
4813
+			$this->parsingCss->fontSet();
4814
+
4815
+			return true;
4816
+		}
4817
+
4818
+		/**
4819
+		 * tag : TABLE
4820
+		 * mode : OPEN
4821
+		 *
4822
+		 * @param  array $param
4823
+		 * @return boolean
4824
+		 */
4825
+		protected function _tag_open_TABLE($param, $other = 'table')
4826
+		{
4827
+			if ($this->_maxH) {
4828
+				if ($this->_isForOneLine) return false;
4829
+				$this->_tag_open_BR(array());
4830
+			}
4831
+
4832
+			if ($this->_isForOneLine) {
4833
+				$this->_maxX = $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
4834
+				return false;
4835
+			}
4836
+
4837
+			$this->_maxH = 0;
4838
+
4839
+			$alignObject = isset($param['align']) ? strtolower($param['align']) : 'left';
4840
+			if (isset($param['align'])) unset($param['align']);
4841
+			if (!in_array($alignObject, array('left', 'center', 'right'))) $alignObject = 'left';
4842
+
4843
+			$this->parsingCss->save();
4844
+			$this->parsingCss->analyse($other, $param);
4845
+			$this->parsingCss->setPosition();
4846
+			$this->parsingCss->fontSet();
4847
+
4848
+			if ($this->parsingCss->value['margin-auto']) $alignObject = 'center';
4849
+
4850
+			// collapse table ?
4851
+			$collapse = false;
4852
+			if ($other=='table') {
4853
+				$collapse = isset($this->parsingCss->value['border']['collapse']) ? $this->parsingCss->value['border']['collapse'] : false;
4854
+			}
4855
+
4856
+			// if collapse => no borders for the table, only for TD
4857
+			if ($collapse) {
4858
+				$param['style']['border'] = 'none';
4859
+				$param['cellspacing'] = 0;
4860
+				$none = $this->parsingCss->readBorder('none');
4861
+				$this->parsingCss->value['border']['t'] = $none;
4862
+				$this->parsingCss->value['border']['r'] = $none;
4863
+				$this->parsingCss->value['border']['b'] = $none;
4864
+				$this->parsingCss->value['border']['l'] = $none;
4865
+			}
4866
+
4867
+			// if we are in a SUB html => prepare the properties of the table
4868
+			if ($this->_subPart) {
4869
+				if ($this->_debugActif) $this->_DEBUG_add('Table n'.$param['num'], true);
4870
+				HTML2PDF::$_tables[$param['num']] = array();
4871
+				HTML2PDF::$_tables[$param['num']]['border']          = isset($param['border']) ? $this->parsingCss->readBorder($param['border']) : null;
4872
+				HTML2PDF::$_tables[$param['num']]['cellpadding']     = $this->parsingCss->ConvertToMM(isset($param['cellpadding']) ? $param['cellpadding'] : '1px');
4873
+				HTML2PDF::$_tables[$param['num']]['cellspacing']     = $this->parsingCss->ConvertToMM(isset($param['cellspacing']) ? $param['cellspacing'] : '2px');
4874
+				HTML2PDF::$_tables[$param['num']]['cases']           = array();          // properties of each TR/TD
4875
+				HTML2PDF::$_tables[$param['num']]['corr']            = array();          // link between TR/TD and colspan/rowspan
4876
+				HTML2PDF::$_tables[$param['num']]['corr_x']          = 0;                // position in 'cases'
4877
+				HTML2PDF::$_tables[$param['num']]['corr_y']          = 0;                // position in 'cases'
4878
+				HTML2PDF::$_tables[$param['num']]['td_curr']         = 0;                // current column
4879
+				HTML2PDF::$_tables[$param['num']]['tr_curr']         = 0;                // current row
4880
+				HTML2PDF::$_tables[$param['num']]['curr_x']          = $this->pdf->getX();
4881
+				HTML2PDF::$_tables[$param['num']]['curr_y']          = $this->pdf->getY();
4882
+				HTML2PDF::$_tables[$param['num']]['width']           = 0;                // global width
4883
+				HTML2PDF::$_tables[$param['num']]['height']          = 0;                // global height
4884
+				HTML2PDF::$_tables[$param['num']]['align']           = $alignObject;
4885
+				HTML2PDF::$_tables[$param['num']]['marge']           = array();
4886
+				HTML2PDF::$_tables[$param['num']]['marge']['t']      = $this->parsingCss->value['padding']['t']+$this->parsingCss->value['border']['t']['width']+HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5;
4887
+				HTML2PDF::$_tables[$param['num']]['marge']['r']      = $this->parsingCss->value['padding']['r']+$this->parsingCss->value['border']['r']['width']+HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5;
4888
+				HTML2PDF::$_tables[$param['num']]['marge']['b']      = $this->parsingCss->value['padding']['b']+$this->parsingCss->value['border']['b']['width']+HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5;
4889
+				HTML2PDF::$_tables[$param['num']]['marge']['l']      = $this->parsingCss->value['padding']['l']+$this->parsingCss->value['border']['l']['width']+HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5;
4890
+				HTML2PDF::$_tables[$param['num']]['page']            = 0;                // number of pages
4891
+				HTML2PDF::$_tables[$param['num']]['new_page']        = true;             // flag : new page for the current TR
4892
+				HTML2PDF::$_tables[$param['num']]['style_value']     = null;             // CSS style of the table
4893
+				HTML2PDF::$_tables[$param['num']]['thead']           = array();          // properties on the thead
4894
+				HTML2PDF::$_tables[$param['num']]['tfoot']           = array();          // properties on the tfoot
4895
+				HTML2PDF::$_tables[$param['num']]['thead']['tr']     = array();          // list of the TRs in the thead
4896
+				HTML2PDF::$_tables[$param['num']]['tfoot']['tr']     = array();          // list of the TRs in the tfoot
4897
+				HTML2PDF::$_tables[$param['num']]['thead']['height']    = 0;             // thead height
4898
+				HTML2PDF::$_tables[$param['num']]['tfoot']['height']    = 0;             // tfoot height
4899
+				HTML2PDF::$_tables[$param['num']]['thead']['code'] = array();            // HTML content of the thead
4900
+				HTML2PDF::$_tables[$param['num']]['tfoot']['code'] = array();            // HTML content of the tfoot
4901
+				HTML2PDF::$_tables[$param['num']]['cols']        = array();              // properties of the COLs
4902
+
4903
+				$this->_saveMargin($this->pdf->getlMargin(), $this->pdf->gettMargin(), $this->pdf->getrMargin());
4904
+
4905
+				$this->parsingCss->value['width']-= HTML2PDF::$_tables[$param['num']]['marge']['l'] + HTML2PDF::$_tables[$param['num']]['marge']['r'];
4906
+			} else {
4907
+				// we start from the first page and the first page of the table
4908
+				HTML2PDF::$_tables[$param['num']]['page'] = 0;
4909
+				HTML2PDF::$_tables[$param['num']]['td_curr']    = 0;
4910
+				HTML2PDF::$_tables[$param['num']]['tr_curr']    = 0;
4911
+				HTML2PDF::$_tables[$param['num']]['td_x']        = HTML2PDF::$_tables[$param['num']]['marge']['l']+HTML2PDF::$_tables[$param['num']]['curr_x'];
4912
+				HTML2PDF::$_tables[$param['num']]['td_y']        = HTML2PDF::$_tables[$param['num']]['marge']['t']+HTML2PDF::$_tables[$param['num']]['curr_y'];
4913
+
4914
+				// draw the borders/background of the first page/part of the table
4915
+				$this->_drawRectangle(
4916
+					HTML2PDF::$_tables[$param['num']]['curr_x'],
4917
+					HTML2PDF::$_tables[$param['num']]['curr_y'],
4918
+					HTML2PDF::$_tables[$param['num']]['width'],
4919
+					isset(HTML2PDF::$_tables[$param['num']]['height'][0]) ? HTML2PDF::$_tables[$param['num']]['height'][0] : null,
4920
+					$this->parsingCss->value['border'],
4921
+					$this->parsingCss->value['padding'],
4922
+					0,
4923
+					$this->parsingCss->value['background']
4924
+				);
4925
+
4926
+				HTML2PDF::$_tables[$param['num']]['style_value'] = $this->parsingCss->value;
4927
+			}
4928
+
4929
+			return true;
4930
+		}
4931
+
4932
+		/**
4933
+		 * tag : TABLE
4934
+		 * mode : CLOSE
4935
+		 *
4936
+		 * @param  array $param
4937
+		 * @return boolean
4938
+		 */
4939
+		protected function _tag_close_TABLE($param)
4940
+		{
4941
+			if ($this->_isForOneLine) return false;
4942
+
4943
+			$this->_maxH = 0;
4944
+
4945
+			// if we are in a sub HTML
4946
+			if ($this->_subPart) {
4947
+				// calculate the size of each case
4948
+				$this->_calculateTableCellSize(HTML2PDF::$_tables[$param['num']]['cases'], HTML2PDF::$_tables[$param['num']]['corr']);
4949
+
4950
+				// calculate the height of the thead and the tfoot
4951
+				$lst = array('thead', 'tfoot');
4952
+				foreach ($lst as $mode) {
4953
+					HTML2PDF::$_tables[$param['num']][$mode]['height'] = 0;
4954
+					foreach (HTML2PDF::$_tables[$param['num']][$mode]['tr'] as $tr) {
4955
+						// hauteur de la ligne tr
4956
+						$h = 0;
4957
+						for ($i=0; $i<count(HTML2PDF::$_tables[$param['num']]['cases'][$tr]); $i++)
4958
+							if (HTML2PDF::$_tables[$param['num']]['cases'][$tr][$i]['rowspan']==1)
4959
+								$h = max($h, HTML2PDF::$_tables[$param['num']]['cases'][$tr][$i]['h']);
4960
+						HTML2PDF::$_tables[$param['num']][$mode]['height']+= $h;
4961
+					}
4962
+				}
4963
+
4964
+				// calculate the width of the table
4965
+				HTML2PDF::$_tables[$param['num']]['width'] = HTML2PDF::$_tables[$param['num']]['marge']['l'] + HTML2PDF::$_tables[$param['num']]['marge']['r'];
4966
+				if (isset(HTML2PDF::$_tables[$param['num']]['cases'][0])) {
4967
+					foreach (HTML2PDF::$_tables[$param['num']]['cases'][0] as $case) {
4968
+						HTML2PDF::$_tables[$param['num']]['width']+= $case['w'];
4969
+					}
4970
+				}
4971
+
4972
+				// X position of the table
4973
+				$old = $this->parsingCss->getOldValues();
4974
+				$parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
4975
+				$x = HTML2PDF::$_tables[$param['num']]['curr_x'];
4976
+				$w = HTML2PDF::$_tables[$param['num']]['width'];
4977
+				if ($parentWidth>$w) {
4978
+					if (HTML2PDF::$_tables[$param['num']]['align']=='center')
4979
+						$x = $x + ($parentWidth-$w)*0.5;
4980
+					else if (HTML2PDF::$_tables[$param['num']]['align']=='right')
4981
+						$x = $x + $parentWidth-$w;
4982
+
4983
+					HTML2PDF::$_tables[$param['num']]['curr_x'] = $x;
4984
+				}
4985
+
4986
+				// calculate the height of the table
4987
+				HTML2PDF::$_tables[$param['num']]['height'] = array();
4988
+
4989
+				// minimum of the height because of margins, and of the thead and tfoot height
4990
+				$h0 = HTML2PDF::$_tables[$param['num']]['marge']['t'] + HTML2PDF::$_tables[$param['num']]['marge']['b'];
4991
+				$h0+= HTML2PDF::$_tables[$param['num']]['thead']['height'] + HTML2PDF::$_tables[$param['num']]['tfoot']['height'];
4992
+
4993
+				// max height of the page
4994
+				$max = $this->pdf->getH() - $this->pdf->getbMargin();
4995
+
4996
+				// current position on the page
4997
+				$y = HTML2PDF::$_tables[$param['num']]['curr_y'];
4998
+				$height = $h0;
4999
+
5000
+				// we get the height of each line
5001
+				for ($k=0; $k<count(HTML2PDF::$_tables[$param['num']]['cases']); $k++) {
5002
+
5003
+					// if it is a TR of the thead or of the tfoot => skip
5004
+					if (in_array($k, HTML2PDF::$_tables[$param['num']]['thead']['tr'])) continue;
5005
+					if (in_array($k, HTML2PDF::$_tables[$param['num']]['tfoot']['tr'])) continue;
5006
+
5007
+					// height of the line
5008
+					$th = 0;
5009
+					$h = 0;
5010
+					for ($i=0; $i<count(HTML2PDF::$_tables[$param['num']]['cases'][$k]); $i++) {
5011
+						$h = max($h, HTML2PDF::$_tables[$param['num']]['cases'][$k][$i]['h']);
5012
+
5013
+						if (HTML2PDF::$_tables[$param['num']]['cases'][$k][$i]['rowspan']==1)
5014
+							$th = max($th, HTML2PDF::$_tables[$param['num']]['cases'][$k][$i]['h']);
5015
+					}
5016
+
5017
+					// if the row does not fit on the page => new page
5018
+					if ($y+$h+$height>$max) {
5019
+						if ($height==$h0) $height = null;
5020
+						HTML2PDF::$_tables[$param['num']]['height'][] = $height;
5021
+						$height = $h0;
5022
+						$y = $this->_margeTop;
5023
+					}
5024
+					$height+= $th;
5025
+				}
5026
+
5027
+				// if ther is a height at the end, add it
5028
+				if ($height!=$h0 || $k==0) HTML2PDF::$_tables[$param['num']]['height'][] = $height;
5029
+			} else {
5030
+				// if we have tfoor, draw it
5031
+				if (count(HTML2PDF::$_tables[$param['num']]['tfoot']['code'])) {
5032
+					$tmpTR = HTML2PDF::$_tables[$param['num']]['tr_curr'];
5033
+					$tmpTD = HTML2PDF::$_tables[$param['num']]['td_curr'];
5034
+					$oldParsePos = $this->_parsePos;
5035
+					$oldParseCode = $this->parsingHtml->code;
5036
+
5037
+					HTML2PDF::$_tables[$param['num']]['tr_curr'] = HTML2PDF::$_tables[$param['num']]['tfoot']['tr'][0];
5038
+					HTML2PDF::$_tables[$param['num']]['td_curr'] = 0;
5039
+					$this->_parsePos = 0;
5040
+					$this->parsingHtml->code = HTML2PDF::$_tables[$param['num']]['tfoot']['code'];
5041
+					$this->_isInTfoot = true;
5042
+					$this->_makeHTMLcode();
5043
+					$this->_isInTfoot = false;
5044
+
5045
+					$this->_parsePos =     $oldParsePos;
5046
+					$this->parsingHtml->code = $oldParseCode;
5047
+					HTML2PDF::$_tables[$param['num']]['tr_curr'] = $tmpTR;
5048
+					HTML2PDF::$_tables[$param['num']]['td_curr'] = $tmpTD;
5049
+				}
5050
+
5051
+				// get the positions of the end of the table
5052
+				$x = HTML2PDF::$_tables[$param['num']]['curr_x'] + HTML2PDF::$_tables[$param['num']]['width'];
5053
+				if (count(HTML2PDF::$_tables[$param['num']]['height'])>1)
5054
+					$y = $this->_margeTop+HTML2PDF::$_tables[$param['num']]['height'][count(HTML2PDF::$_tables[$param['num']]['height'])-1];
5055
+				else if (count(HTML2PDF::$_tables[$param['num']]['height'])==1)
5056
+					$y = HTML2PDF::$_tables[$param['num']]['curr_y']+HTML2PDF::$_tables[$param['num']]['height'][count(HTML2PDF::$_tables[$param['num']]['height'])-1];
5057
+				else
5058
+					$y = HTML2PDF::$_tables[$param['num']]['curr_y'];
5059
+
5060
+				$this->_maxX = max($this->_maxX, $x);
5061
+				$this->_maxY = max($this->_maxY, $y);
5062
+
5063
+				$this->pdf->setXY($this->pdf->getlMargin(), $y);
5064
+
5065
+				$this->_loadMargin();
5066
+
5067
+				if ($this->_debugActif) $this->_DEBUG_add('Table '.$param['num'], false);
5068
+			}
5069
+
5070
+			$this->parsingCss->load();
5071
+			$this->parsingCss->fontSet();
5072
+
5073
+
5074
+			return true;
5075
+		}
5076
+
5077
+		/**
5078
+		 * tag : COL
5079
+		 * mode : OPEN
5080
+		 *
5081
+		 * @param  array $param
5082
+		 * @return boolean
5083
+		 */
5084
+		protected function _tag_open_COL($param)
5085
+		{
5086
+			$span = isset($param['span']) ? $param['span'] : 1;
5087
+			for ($k=0; $k<$span; $k++)
5088
+				HTML2PDF::$_tables[$param['num']]['cols'][] = $param;
5089
+		}
5090
+
5091
+		/**
5092
+		 * tag : COL
5093
+		 * mode : CLOSE
5094
+		 *
5095
+		 * @param  array $param
5096
+		 * @return boolean
5097
+		 */
5098
+		protected function _tag_close_COL($param)
5099
+		{
5100
+			// there is nothing to do here
5101
+
5102
+			return true;
5103
+		}
5104
+
5105
+		/**
5106
+		 * tag : TR
5107
+		 * mode : OPEN
5108
+		 *
5109
+		 * @param  array $param
5110
+		 * @return boolean
5111
+		 */
5112
+		protected function _tag_open_TR($param, $other = 'tr')
5113
+		{
5114
+			if ($this->_isForOneLine) return false;
5115
+
5116
+			$this->_maxH = 0;
5117
+
5118
+			$this->parsingCss->save();
5119
+			$this->parsingCss->analyse($other, $param);
5120
+			$this->parsingCss->setPosition();
5121
+			$this->parsingCss->fontSet();
5122
+
5123
+			// position in the table
5124
+			HTML2PDF::$_tables[$param['num']]['tr_curr']++;
5125
+			HTML2PDF::$_tables[$param['num']]['td_curr']= 0;
5126
+
5127
+			// if we are not in a sub html
5128
+			if (!$this->_subPart) {
5129
+
5130
+				// Y after the row
5131
+				$ty=null;
5132
+				for ($ii=0; $ii<count(HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1]); $ii++) {
5133
+					$ty = max($ty, HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][$ii]['h']);
5134
+				}
5135
+
5136
+				// height of the tfoot
5137
+				$hfoot = HTML2PDF::$_tables[$param['num']]['tfoot']['height'];
5138
+
5139
+				// if the line does not fit on the page => new page
5140
+				if (!$this->_isInTfoot && HTML2PDF::$_tables[$param['num']]['td_y'] + HTML2PDF::$_tables[$param['num']]['marge']['b'] + $ty +$hfoot> $this->pdf->getH() - $this->pdf->getbMargin()) {
5141
+
5142
+					// fi ther is a tfoot => draw it
5143
+					if (count(HTML2PDF::$_tables[$param['num']]['tfoot']['code'])) {
5144
+						$tmpTR = HTML2PDF::$_tables[$param['num']]['tr_curr'];
5145
+						$tmpTD = HTML2PDF::$_tables[$param['num']]['td_curr'];
5146
+						$oldParsePos = $this->_parsePos;
5147
+						$oldParseCode = $this->parsingHtml->code;
5148
+
5149
+						HTML2PDF::$_tables[$param['num']]['tr_curr'] = HTML2PDF::$_tables[$param['num']]['tfoot']['tr'][0];
5150
+						HTML2PDF::$_tables[$param['num']]['td_curr'] = 0;
5151
+						$this->_parsePos = 0;
5152
+						$this->parsingHtml->code = HTML2PDF::$_tables[$param['num']]['tfoot']['code'];
5153
+						$this->_isInTfoot = true;
5154
+						$this->_makeHTMLcode();
5155
+						$this->_isInTfoot = false;
5156
+
5157
+						$this->_parsePos =     $oldParsePos;
5158
+						$this->parsingHtml->code = $oldParseCode;
5159
+						HTML2PDF::$_tables[$param['num']]['tr_curr'] = $tmpTR;
5160
+						HTML2PDF::$_tables[$param['num']]['td_curr'] = $tmpTD;
5161
+					}
5162
+
5163
+					// new page
5164
+					HTML2PDF::$_tables[$param['num']]['new_page'] = true;
5165
+					$this->_setNewPage();
5166
+
5167
+					// new position
5168
+					HTML2PDF::$_tables[$param['num']]['page']++;
5169
+					HTML2PDF::$_tables[$param['num']]['curr_y'] = $this->pdf->getY();
5170
+					HTML2PDF::$_tables[$param['num']]['td_y'] = HTML2PDF::$_tables[$param['num']]['curr_y']+HTML2PDF::$_tables[$param['num']]['marge']['t'];
5171
+
5172
+					// if we have the height of the tbale on the page => draw borders and background
5173
+					if (isset(HTML2PDF::$_tables[$param['num']]['height'][HTML2PDF::$_tables[$param['num']]['page']])) {
5174
+						$old = $this->parsingCss->value;
5175
+						$this->parsingCss->value = HTML2PDF::$_tables[$param['num']]['style_value'];
5176
+
5177
+						$this->_drawRectangle(
5178
+							HTML2PDF::$_tables[$param['num']]['curr_x'],
5179
+							HTML2PDF::$_tables[$param['num']]['curr_y'],
5180
+							HTML2PDF::$_tables[$param['num']]['width'],
5181
+							HTML2PDF::$_tables[$param['num']]['height'][HTML2PDF::$_tables[$param['num']]['page']],
5182
+							$this->parsingCss->value['border'],
5183
+							$this->parsingCss->value['padding'],
5184
+							HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5,
5185
+							$this->parsingCss->value['background']
5186
+						);
5187
+
5188
+						$this->parsingCss->value = $old;
5189
+					}
5190
+				}
5191
+
5192
+				// if we are in a new page, and if we have a thead => draw it
5193
+				if (HTML2PDF::$_tables[$param['num']]['new_page'] && count(HTML2PDF::$_tables[$param['num']]['thead']['code'])) {
5194
+					HTML2PDF::$_tables[$param['num']]['new_page'] = false;
5195
+					$tmpTR = HTML2PDF::$_tables[$param['num']]['tr_curr'];
5196
+					$tmpTD = HTML2PDF::$_tables[$param['num']]['td_curr'];
5197
+					$oldParsePos = $this->_parsePos;
5198
+					$oldParseCode = $this->parsingHtml->code;
5199
+
5200
+					HTML2PDF::$_tables[$param['num']]['tr_curr'] = HTML2PDF::$_tables[$param['num']]['thead']['tr'][0];
5201
+					HTML2PDF::$_tables[$param['num']]['td_curr'] = 0;
5202
+					$this->_parsePos = 0;
5203
+					$this->parsingHtml->code = HTML2PDF::$_tables[$param['num']]['thead']['code'];
5204
+					$this->_isInThead = true;
5205
+					$this->_makeHTMLcode();
5206
+					$this->_isInThead = false;
5207
+
5208
+					$this->_parsePos =     $oldParsePos;
5209
+					$this->parsingHtml->code = $oldParseCode;
5210
+					HTML2PDF::$_tables[$param['num']]['tr_curr'] = $tmpTR;
5211
+					HTML2PDF::$_tables[$param['num']]['td_curr'] = $tmpTD;
5212
+					HTML2PDF::$_tables[$param['num']]['new_page'] = true;
5213
+				}
5214
+			// else (in a sub HTML)
5215
+			} else {
5216
+				// prepare it
5217
+				HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1] = array();
5218
+				if (!isset(HTML2PDF::$_tables[$param['num']]['corr'][HTML2PDF::$_tables[$param['num']]['corr_y']]))
5219
+					HTML2PDF::$_tables[$param['num']]['corr'][HTML2PDF::$_tables[$param['num']]['corr_y']] = array();
5220
+
5221
+				HTML2PDF::$_tables[$param['num']]['corr_x']=0;
5222
+				while(isset(HTML2PDF::$_tables[$param['num']]['corr'][HTML2PDF::$_tables[$param['num']]['corr_y']][HTML2PDF::$_tables[$param['num']]['corr_x']]))
5223
+					HTML2PDF::$_tables[$param['num']]['corr_x']++;
5224
+			}
5225
+
5226
+			return true;
5227
+		}
5228
+
5229
+		/**
5230
+		 * tag : TR
5231
+		 * mode : CLOSE
5232
+		 *
5233
+		 * @param  array $param
5234
+		 * @return boolean
5235
+		 */
5236
+		protected function _tag_close_TR($param)
5237
+		{
5238
+			if ($this->_isForOneLine) return false;
5239
+
5240
+			$this->_maxH = 0;
5241
+
5242
+			$this->parsingCss->load();
5243
+			$this->parsingCss->fontSet();
5244
+
5245
+			// if we are not in a sub HTML
5246
+			if (!$this->_subPart) {
5247
+
5248
+				// Y of the current line
5249
+				$ty=null;
5250
+				for ($ii=0; $ii<count(HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1]); $ii++) {
5251
+					if (HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][$ii]['rowspan']==1) {
5252
+						$ty = HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][$ii]['h'];
5253
+					}
5254
+				}
5255
+
5256
+				// new position
5257
+				HTML2PDF::$_tables[$param['num']]['td_x'] = HTML2PDF::$_tables[$param['num']]['curr_x']+HTML2PDF::$_tables[$param['num']]['marge']['l'];
5258
+				HTML2PDF::$_tables[$param['num']]['td_y']+= $ty;
5259
+				HTML2PDF::$_tables[$param['num']]['new_page'] = false;
5260
+			} else {
5261
+				HTML2PDF::$_tables[$param['num']]['corr_y']++;
5262
+			}
5263
+
5264
+			return true;
5265
+		}
5266
+
5267
+		/**
5268
+		 * tag : TD
5269
+		 * mode : OPEN
5270
+		 *
5271
+		 * @param  array $param
5272
+		 * @return boolean
5273
+		 */
5274
+		protected function _tag_open_TD($param, $other = 'td')
5275
+		{
5276
+			if ($this->_isForOneLine) return false;
5277
+
5278
+			$this->_maxH = 0;
5279
+
5280
+			$param['cellpadding'] = HTML2PDF::$_tables[$param['num']]['cellpadding'].'mm';
5281
+			$param['cellspacing'] = HTML2PDF::$_tables[$param['num']]['cellspacing'].'mm';
5282
+
5283
+			// specific style for LI
5284
+			if ($other=='li') {
5285
+				$specialLi = true;
5286
+			} else {
5287
+				$specialLi = false;
5288
+				if ($other=='li_sub') {
5289
+					$param['style']['border'] = 'none';
5290
+					$param['style']['background-color']    = 'transparent';
5291
+					$param['style']['background-image']    = 'none';
5292
+					$param['style']['background-position'] = '';
5293
+					$param['style']['background-repeat']   = '';
5294
+					$other = 'li';
5295
+				}
5296
+			}
5297
+
5298
+			// get the properties of the TD
5299
+			$x = HTML2PDF::$_tables[$param['num']]['td_curr'];
5300
+			$y = HTML2PDF::$_tables[$param['num']]['tr_curr']-1;
5301
+			$colspan = isset($param['colspan']) ? $param['colspan'] : 1;
5302
+			$rowspan = isset($param['rowspan']) ? $param['rowspan'] : 1;
5303
+
5304
+			// flag for collapse table
5305
+			$collapse = false;
5306
+
5307
+			// specific traitment for TD and TH
5308
+			if (in_array($other, array('td', 'th'))) {
5309
+				// id of the column
5310
+				$numCol = isset(HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['Xr']) ? HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['Xr'] : HTML2PDF::$_tables[$param['num']]['corr_x'];
5311
+
5312
+				// we get the properties of the COL tag, if exist
5313
+				if (isset(HTML2PDF::$_tables[$param['num']]['cols'][$numCol])) {
5314
+
5315
+					$colParam = HTML2PDF::$_tables[$param['num']]['cols'][$numCol];
5316
+
5317
+					// for colspans => we get all the neede widths
5318
+					$colParam['style']['width'] = array();
5319
+					for ($k=0; $k<$colspan; $k++) {
5320
+						if (isset(HTML2PDF::$_tables[$param['num']]['cols'][$numCol+$k]['style']['width'])) {
5321
+							$colParam['style']['width'][] = HTML2PDF::$_tables[$param['num']]['cols'][$numCol+$k]['style']['width'];
5322
+						}
5323
+					}
5324
+
5325
+					// calculate the total width of the column
5326
+					$total = '';
5327
+					$last = $this->parsingCss->getLastWidth();
5328
+					if (count($colParam['style']['width'])) {
5329
+						$total = $colParam['style']['width'][0]; unset($colParam['style']['width'][0]);
5330
+						foreach ($colParam['style']['width'] as $width) {
5331
+							if (substr($total, -1)=='%' && substr($width, -1)=='%')
5332
+								$total = (str_replace('%', '', $total)+str_replace('%', '', $width)).'%';
5333
+							else
5334
+								$total = ($this->parsingCss->ConvertToMM($total, $last) + $this->parsingCss->ConvertToMM($width, $last)).'mm';
5335
+						}
5336
+					}
5337
+
5338
+					// get the final width
5339
+					if ($total) {
5340
+						$colParam['style']['width'] = $total;
5341
+					} else {
5342
+						unset($colParam['style']['width']);
5343
+					}
5344
+
5345
+
5346
+					// merge the styles of the COL and the TD
5347
+					$param['style'] = array_merge($colParam['style'], $param['style']);
5348
+
5349
+					// merge the class of the COL and the TD
5350
+					if (isset($colParam['class'])) {
5351
+						$param['class'] = $colParam['class'].(isset($param['class']) ? ' '.$param['class'] : '');
5352
+					}
5353
+				}
5354
+
5355
+				$collapse = isset($this->parsingCss->value['border']['collapse']) ? $this->parsingCss->value['border']['collapse'] : false;
5356
+			}
5357
+
5358
+			$this->parsingCss->save();
5359
+
5360
+			// legacy for TD and TH
5361
+			$legacy = null;
5362
+			if (in_array($other, array('td', 'th'))) {
5363
+				$legacy = array();
5364
+
5365
+				$old = $this->parsingCss->getLastValue('background');
5366
+				if ($old && ($old['color'] || $old['image']))
5367
+					$legacy['background'] = $old;
5368
+
5369
+				if (HTML2PDF::$_tables[$param['num']]['border']) {
5370
+					$legacy['border'] = array();
5371
+					$legacy['border']['l'] = HTML2PDF::$_tables[$param['num']]['border'];
5372
+					$legacy['border']['t'] = HTML2PDF::$_tables[$param['num']]['border'];
5373
+					$legacy['border']['r'] = HTML2PDF::$_tables[$param['num']]['border'];
5374
+					$legacy['border']['b'] = HTML2PDF::$_tables[$param['num']]['border'];
5375
+				}
5376
+			}
5377
+			$return = $this->parsingCss->analyse($other, $param, $legacy);
5378
+
5379
+			if ($specialLi) {
5380
+				$this->parsingCss->value['width']-= $this->parsingCss->ConvertToMM($this->_listeGetWidth());
5381
+				$this->parsingCss->value['width']-= $this->parsingCss->ConvertToMM($this->_listeGetPadding());
5382
+			}
5383
+			$this->parsingCss->setPosition();
5384
+			$this->parsingCss->fontSet();
5385
+
5386
+			// if tale collapse => modify the borders
5387
+			if ($collapse) {
5388
+				if (!$this->_subPart) {
5389
+					if (
5390
+						(HTML2PDF::$_tables[$param['num']]['tr_curr']>1 && !HTML2PDF::$_tables[$param['num']]['new_page']) ||
5391
+						(!$this->_isInThead && count(HTML2PDF::$_tables[$param['num']]['thead']['code']))
5392
+					) {
5393
+						$this->parsingCss->value['border']['t'] = $this->parsingCss->readBorder('none');
5394
+					}
5395
+				}
5396
+
5397
+				if (HTML2PDF::$_tables[$param['num']]['td_curr']>0) {
5398
+					if (!$return) $this->parsingCss->value['width']+= $this->parsingCss->value['border']['l']['width'];
5399
+					$this->parsingCss->value['border']['l'] = $this->parsingCss->readBorder('none');
5400
+				}
5401
+			}
5402
+
5403
+			// margins of the table
5404
+			$marge = array();
5405
+			$marge['t'] = $this->parsingCss->value['padding']['t']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['t']['width'];
5406
+			$marge['r'] = $this->parsingCss->value['padding']['r']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['r']['width'];
5407
+			$marge['b'] = $this->parsingCss->value['padding']['b']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['b']['width'];
5408
+			$marge['l'] = $this->parsingCss->value['padding']['l']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['l']['width'];
5409
+
5410
+			// if we are in a sub HTML
5411
+			if ($this->_subPart) {
5412
+				// new position in the table
5413
+				HTML2PDF::$_tables[$param['num']]['td_curr']++;
5414
+				HTML2PDF::$_tables[$param['num']]['cases'][$y][$x] = array();
5415
+				HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['w'] = 0;
5416
+				HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['h'] = 0;
5417
+				HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['dw'] = 0;
5418
+				HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['colspan'] = $colspan;
5419
+				HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['rowspan'] = $rowspan;
5420
+				HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['Xr'] = HTML2PDF::$_tables[$param['num']]['corr_x'];
5421
+				HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['Yr'] = HTML2PDF::$_tables[$param['num']]['corr_y'];
5422
+
5423
+				// prepare the mapping for rowspan and colspan
5424
+				for ($j=0; $j<$rowspan; $j++) {
5425
+					for ($i=0; $i<$colspan; $i++) {
5426
+						HTML2PDF::$_tables[$param['num']]['corr']
5427
+							[HTML2PDF::$_tables[$param['num']]['corr_y']+$j]
5428
+							[HTML2PDF::$_tables[$param['num']]['corr_x']+$i] = ($i+$j>0) ? '' : array($x,$y,$colspan,$rowspan);
5429
+					}
5430
+				}
5431
+				HTML2PDF::$_tables[$param['num']]['corr_x']+= $colspan;
5432
+				while (isset(HTML2PDF::$_tables[$param['num']]['corr'][HTML2PDF::$_tables[$param['num']]['corr_y']][HTML2PDF::$_tables[$param['num']]['corr_x']])) {
5433
+					HTML2PDF::$_tables[$param['num']]['corr_x']++;
5434
+				}
5435
+
5436
+				// extract the content of the TD, and calculate his size
5437
+				$level = $this->parsingHtml->getLevel($this->_tempPos);
5438
+				$this->_createSubHTML($this->_subHtml);
5439
+				$this->_subHtml->parsingHtml->code = $level;
5440
+				$this->_subHtml->_makeHTMLcode();
5441
+				$this->_tempPos+= count($level);
5442
+			} else {
5443
+				// new position in the table
5444
+				HTML2PDF::$_tables[$param['num']]['td_curr']++;
5445
+				HTML2PDF::$_tables[$param['num']]['td_x']+= HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['dw'];
5446
+
5447
+				// borders and background of the TD
5448
+				$this->_drawRectangle(
5449
+					HTML2PDF::$_tables[$param['num']]['td_x'],
5450
+					HTML2PDF::$_tables[$param['num']]['td_y'],
5451
+					HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['w'],
5452
+					HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['h'],
5453
+					$this->parsingCss->value['border'],
5454
+					$this->parsingCss->value['padding'],
5455
+					HTML2PDF::$_tables[$param['num']]['cellspacing']*0.5,
5456
+					$this->parsingCss->value['background']
5457
+				);
5458
+
5459
+				$this->parsingCss->value['width'] = HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['w'] - $marge['l'] - $marge['r'];
5460
+
5461
+				// marges = size of the TD
5462
+				$mL = HTML2PDF::$_tables[$param['num']]['td_x']+$marge['l'];
5463
+				$mR = $this->pdf->getW() - $mL - $this->parsingCss->value['width'];
5464
+				$this->_saveMargin($mL, 0, $mR);
5465
+
5466
+				// position of the content, from vertical-align
5467
+				$hCorr = HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['h'];
5468
+				$hReel = HTML2PDF::$_tables[$param['num']]['cases'][$y][$x]['real_h'];
5469
+				switch($this->parsingCss->value['vertical-align'])
5470
+				{
5471
+					case 'bottom':
5472
+						$yCorr = $hCorr-$hReel;
5473
+						break;
5474
+
5475
+					case 'middle':
5476
+						$yCorr = ($hCorr-$hReel)*0.5;
5477
+						break;
5478
+
5479
+					case 'top':
5480
+					default:
5481
+						$yCorr = 0;
5482
+						break;
5483
+				}
5484
+
5485
+				//  position of the content
5486
+				$x = HTML2PDF::$_tables[$param['num']]['td_x']+$marge['l'];
5487
+				$y = HTML2PDF::$_tables[$param['num']]['td_y']+$marge['t']+$yCorr;
5488
+				$this->pdf->setXY($x, $y);
5489
+				$this->_setNewPositionForNewLine();
5490
+			}
5491
+
5492
+			return true;
5493
+		}
5494
+
5495
+		/**
5496
+		 * tag : TD
5497
+		 * mode : CLOSE
5498
+		 *
5499
+		 * @param    array $param
5500
+		 * @return boolean
5501
+		 */
5502
+		protected function _tag_close_TD($param)
5503
+		{
5504
+			if ($this->_isForOneLine) return false;
5505
+
5506
+			$this->_maxH = 0;
5507
+
5508
+			// get the margins
5509
+			$marge = array();
5510
+			$marge['t'] = $this->parsingCss->value['padding']['t']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['t']['width'];
5511
+			$marge['r'] = $this->parsingCss->value['padding']['r']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['r']['width'];
5512
+			$marge['b'] = $this->parsingCss->value['padding']['b']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['b']['width'];
5513
+			$marge['l'] = $this->parsingCss->value['padding']['l']+0.5*HTML2PDF::$_tables[$param['num']]['cellspacing']+$this->parsingCss->value['border']['l']['width'];
5514
+			$marge['t']+= 0.001;
5515
+			$marge['r']+= 0.001;
5516
+			$marge['b']+= 0.001;
5517
+			$marge['l']+= 0.001;
5518
+
5519
+			// if we are in a sub HTML
5520
+			if ($this->_subPart) {
5521
+
5522
+				// it msut take only one page
5523
+				if ($this->_testTdInOnepage && $this->_subHtml->pdf->getPage()>1) {
5524
+					throw new HTML2PDF_exception(7);
5525
+				}
5526
+
5527
+				// size of the content of the TD
5528
+				$w0 = $this->_subHtml->_maxX + $marge['l'] + $marge['r'];
5529
+				$h0 = $this->_subHtml->_maxY + $marge['t'] + $marge['b'];
5530
+
5531
+				// size from the CSS style
5532
+				$w2 = $this->parsingCss->value['width'] + $marge['l'] + $marge['r'];
5533
+				$h2 = $this->parsingCss->value['height'] + $marge['t'] + $marge['b'];
5534
+
5535
+				// final size of the TD
5536
+				HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][HTML2PDF::$_tables[$param['num']]['td_curr']-1]['w'] = max(array($w0, $w2));
5537
+				HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][HTML2PDF::$_tables[$param['num']]['td_curr']-1]['h'] = max(array($h0, $h2));
5538
+
5539
+				// real position of the content
5540
+				HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][HTML2PDF::$_tables[$param['num']]['td_curr']-1]['real_w'] = $w0;
5541
+				HTML2PDF::$_tables[$param['num']]['cases'][HTML2PDF::$_tables[$param['num']]['tr_curr']-1][HTML2PDF::$_tables[$param['num']]['td_curr']-1]['real_h'] = $h0;
5542
+
5543
+				// destroy the sub HTML
5544
+				$this->_destroySubHTML($this->_subHtml);
5545
+			} else {
5546
+				$this->_loadMargin();
5547
+
5548
+				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'];
5549
+			}
5550
+
5551
+			$this->parsingCss->load();
5552
+			$this->parsingCss->fontSet();
5553
+
5554
+			return true;
5555
+		}
5556
+
5557
+
5558
+		/**
5559
+		 * tag : TH
5560
+		 * mode : OPEN
5561
+		 *
5562
+		 * @param  array $param
5563
+		 * @return boolean
5564
+		 */
5565
+		protected function _tag_open_TH($param)
5566
+		{
5567
+			if ($this->_isForOneLine) return false;
5568
+
5569
+			$this->parsingCss->save();
5570
+			$this->parsingCss->value['font-bold'] = true;
5571
+
5572
+			$this->_tag_open_TD($param, 'th');
5573
+
5574
+			return true;
5575
+		}
5576
+
5577
+		/**
5578
+		 * tag : TH
5579
+		 * mode : CLOSE
5580
+		 *
5581
+		 * @param  array $param
5582
+		 * @return boolean
5583
+		 */
5584
+		protected function _tag_close_TH($param)
5585
+		{
5586
+			if ($this->_isForOneLine) return false;
5587
+
5588
+			$this->_tag_close_TD($param);
5589
+
5590
+			$this->parsingCss->load();
5591
+
5592
+			return true;
5593
+		}
5594
+
5595
+		/**
5596
+		 * tag : IMG
5597
+		 * mode : OPEN
5598
+		 *
5599
+		 * @param  array $param
5600
+		 * @return boolean
5601
+		 */
5602
+		protected function _tag_open_IMG($param)
5603
+		{
5604
+			$src    = str_replace('&amp;', '&', $param['src']);
5605
+
5606
+			$this->parsingCss->save();
5607
+			$this->parsingCss->value['width']    = 0;
5608
+			$this->parsingCss->value['height']    = 0;
5609
+			$this->parsingCss->value['border']    = array('type' => 'none', 'width' => 0, 'color' => array(0, 0, 0));
5610
+			$this->parsingCss->value['background'] = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
5611
+			$this->parsingCss->analyse('img', $param);
5612
+			$this->parsingCss->setPosition();
5613
+			$this->parsingCss->fontSet();
5614
+
5615
+			$res = $this->_drawImage($src, isset($param['sub_li']));
5616
+			if (!$res) return $res;
5617
+
5618
+			$this->parsingCss->load();
5619
+			$this->parsingCss->fontSet();
5620
+			$this->_maxE++;
5621
+
5622
+			return true;
5623
+		}
5624
+
5625
+		/**
5626
+		 * tag : SELECT
5627
+		 * mode : OPEN
5628
+		 *
5629
+		 * @param  array $param
5630
+		 * @return boolean
5631
+		 */
5632
+		protected function _tag_open_SELECT($param)
5633
+		{
5634
+			if (!isset($param['name'])) {
5635
+				$param['name'] = 'champs_pdf_'.(count($this->_lstField)+1);
5636
+			}
5637
+
5638
+			$param['name'] = strtolower($param['name']);
5639
+
5640
+			if (isset($this->_lstField[$param['name']])) {
5641
+				$this->_lstField[$param['name']]++;
5642
+			} else {
5643
+				$this->_lstField[$param['name']] = 1;
5644
+			}
5645
+
5646
+			$this->parsingCss->save();
5647
+			$this->parsingCss->analyse('select', $param);
5648
+			$this->parsingCss->setPosition();
5649
+			$this->parsingCss->fontSet();
5650
+
5651
+			$this->_lstSelect = array();
5652
+			$this->_lstSelect['name']    = $param['name'];
5653
+			$this->_lstSelect['multi']    = isset($param['multiple']) ? true : false;
5654
+			$this->_lstSelect['size']    = isset($param['size']) ? $param['size'] : 1;
5655
+			$this->_lstSelect['options']    = array();
5656
+
5657
+			if ($this->_lstSelect['multi'] && $this->_lstSelect['size']<3) $this->_lstSelect['size'] = 3;
5658
+
5659
+			return true;
5660
+		}
5661
+
5662
+		/**
5663
+		 * tag : OPTION
5664
+		 * mode : OPEN
5665
+		 *
5666
+		 * @param    array $param
5667
+		 * @return boolean
5668
+		 */
5669
+		protected function _tag_open_OPTION($param)
5670
+		{
5671
+			// get the content of the option : it is the text of the option
5672
+			$level = $this->parsingHtml->getLevel($this->_parsePos);
5673
+			$this->_parsePos+= count($level);
5674
+			$value = isset($param['value']) ? $param['value'] : 'aut_tag_open_opt_'.(count($this->_lstSelect)+1);
5675
+
5676
+			$this->_lstSelect['options'][$value] = isset($level[0]['param']['txt']) ? $level[0]['param']['txt'] : '';
5677
+
5678
+			return true;
5679
+		}
5680
+
5681
+		/**
5682
+		 * tag : OPTION
5683
+		 * mode : CLOSE
5684
+		 *
5685
+		 * @param    array $param
5686
+		 * @return boolean
5687
+		 */
5688
+		protected function _tag_close_OPTION($param)
5689
+		{
5690
+			// nothing to do here
5691
+
5692
+			return true;
5693
+		}
5694
+
5695
+		/**
5696
+		 * tag : SELECT
5697
+		 * mode : CLOSE
5698
+		 *
5699
+		 * @param  array $param
5700
+		 * @return boolean
5701
+		 */
5702
+		protected function _tag_close_SELECT()
5703
+		{
5704
+			// position of the select
5705
+			$x = $this->pdf->getX();
5706
+			$y = $this->pdf->getY();
5707
+			$f = 1.08*$this->parsingCss->value['font-size'];
5708
+
5709
+			// width
5710
+			$w = $this->parsingCss->value['width']; if (!$w) $w = 50;
5711
+
5712
+			// height (automatic)
5713
+			$h = ($f*1.07*$this->_lstSelect['size'] + 1);
5714
+
5715
+			$prop = $this->parsingCss->getFormStyle();
5716
+
5717
+			// multy select
5718
+			if ($this->_lstSelect['multi']) {
5719
+				$prop['multipleSelection'] = 'true';
5720
+			}
5721
+
5722
+
5723
+			// single or multi select
5724
+			if ($this->_lstSelect['size']>1) {
5725
+				$this->pdf->ListBox($this->_lstSelect['name'], $w, $h, $this->_lstSelect['options'], $prop);
5726
+			} else {
5727
+				$this->pdf->ComboBox($this->_lstSelect['name'], $w, $h, $this->_lstSelect['options'], $prop);
5728
+			}
5729
+
5730
+			$this->_maxX = max($this->_maxX, $x+$w);
5731
+			$this->_maxY = max($this->_maxY, $y+$h);
5732
+			$this->_maxH = max($this->_maxH, $h);
5733
+			$this->_maxE++;
5734
+			$this->pdf->setX($x+$w);
5735
+
5736
+			$this->parsingCss->load();
5737
+			$this->parsingCss->fontSet();
5738
+
5739
+			$this->_lstSelect = array();
5740
+
5741
+			return true;
5742
+		}
5743
+
5744
+		/**
5745
+		 * tag : TEXTAREA
5746
+		 * mode : OPEN
5747
+		 *
5748
+		 * @param    array $param
5749
+		 * @return boolean
5750
+		 */
5751
+		protected function _tag_open_TEXTAREA($param)
5752
+		{
5753
+			if (!isset($param['name'])) {
5754
+				$param['name'] = 'champs_pdf_'.(count($this->_lstField)+1);
5755
+			}
5756
+
5757
+			$param['name'] = strtolower($param['name']);
5758
+
5759
+			if (isset($this->_lstField[$param['name']])) {
5760
+				$this->_lstField[$param['name']]++;
5761
+			} else {
5762
+				$this->_lstField[$param['name']] = 1;
5763
+			}
5764
+
5765
+			$this->parsingCss->save();
5766
+			$this->parsingCss->analyse('textarea', $param);
5767
+			$this->parsingCss->setPosition();
5768
+			$this->parsingCss->fontSet();
5769
+
5770
+			$x = $this->pdf->getX();
5771
+			$y = $this->pdf->getY();
5772
+			$fx = 0.65*$this->parsingCss->value['font-size'];
5773
+			$fy = 1.08*$this->parsingCss->value['font-size'];
5774
+
5775
+			// extract the content the textarea : value
5776
+			$level = $this->parsingHtml->getLevel($this->_parsePos);
5777
+			$this->_parsePos+= count($level);
5778
+
5779
+			// automatic size, from cols and rows properties
5780
+			$w = $fx*(isset($param['cols']) ? $param['cols'] : 22)+1;
5781
+			$h = $fy*1.07*(isset($param['rows']) ? $param['rows'] : 3)+3;
5782
+
5783
+			$prop = $this->parsingCss->getFormStyle();
5784
+
5785
+			$prop['multiline'] = true;
5786
+			$prop['value'] = isset($level[0]['param']['txt']) ? $level[0]['param']['txt'] : '';
5787
+
5788
+			$this->pdf->TextField($param['name'], $w, $h, $prop, array(), $x, $y);
5789
+
5790
+			$this->_maxX = max($this->_maxX, $x+$w);
5791
+			$this->_maxY = max($this->_maxY, $y+$h);
5792
+			$this->_maxH = max($this->_maxH, $h);
5793
+			$this->_maxE++;
5794
+			$this->pdf->setX($x+$w);
5795
+
5796
+			return true;
5797
+		}
5798
+
5799
+		/**
5800
+		 * tag : TEXTAREA
5801
+		 * mode : CLOSE
5802
+		 *
5803
+		 * @param  array $param
5804
+		 * @return boolean
5805
+		 */
5806
+		protected function _tag_close_TEXTAREA()
5807
+		{
5808
+			$this->parsingCss->load();
5809
+			$this->parsingCss->fontSet();
5810
+
5811
+			return true;
5812
+		}
5813
+
5814
+		/**
5815
+		 * tag : INPUT
5816
+		 * mode : OPEN
5817
+		 *
5818
+		 * @param  array $param
5819
+		 * @return boolean
5820
+		 */
5821
+		protected function _tag_open_INPUT($param)
5822
+		{
5823
+			if (!isset($param['name']))  $param['name']  = 'champs_pdf_'.(count($this->_lstField)+1);
5824
+			if (!isset($param['value'])) $param['value'] = '';
5825
+			if (!isset($param['type']))  $param['type']  = 'text';
5826
+
5827
+			$param['name'] = strtolower($param['name']);
5828
+			$param['type'] = strtolower($param['type']);
5829
+
5830
+			// the type must be valid
5831
+			if (!in_array($param['type'], array('text', 'checkbox', 'radio', 'hidden', 'submit', 'reset', 'button'))) {
5832
+				$param['type'] = 'text';
5833
+			}
5834
+
5835
+			if (isset($this->_lstField[$param['name']])) {
5836
+				$this->_lstField[$param['name']]++;
5837
+			} else {
5838
+				$this->_lstField[$param['name']] = 1;
5839
+			}
5840
+
5841
+			$this->parsingCss->save();
5842
+			$this->parsingCss->analyse('input', $param);
5843
+			$this->parsingCss->setPosition();
5844
+			$this->parsingCss->fontSet();
5845
+
5846
+			$name = $param['name'];
5847
+
5848
+			$x = $this->pdf->getX();
5849
+			$y = $this->pdf->getY();
5850
+			$f = 1.08*$this->parsingCss->value['font-size'];
5851
+
5852
+			$prop = $this->parsingCss->getFormStyle();
5853
+
5854
+			switch($param['type'])
5855
+			{
5856
+				case 'checkbox':
5857
+					$w = 3;
5858
+					$h = $w;
5859
+					if ($h<$f) $y+= ($f-$h)*0.5;
5860
+					$checked = (isset($param['checked']) && $param['checked']=='checked');
5861
+					$this->pdf->CheckBox($name, $w, $checked, $prop, array(), ($param['value'] ? $param['value'] : 'Yes'), $x, $y);
5862
+					break;
5863
+
5864
+				case 'radio':
5865
+					$w = 3;
5866
+					$h = $w;
5867
+					if ($h<$f) $y+= ($f-$h)*0.5;
5868
+					$checked = (isset($param['checked']) && $param['checked']=='checked');
5869
+					$this->pdf->RadioButton($name, $w, $prop, array(), ($param['value'] ? $param['value'] : 'On'), $checked, $x, $y);
5870
+					break;
5871
+
5872
+				case 'hidden':
5873
+					$w = 0;
5874
+					$h = 0;
5875
+					$prop['value'] = $param['value'];
5876
+					$this->pdf->TextField($name, $w, $h, $prop, array(), $x, $y);
5877
+					break;
5878
+
5879
+				case 'text':
5880
+					$w = $this->parsingCss->value['width']; if (!$w) $w = 40;
5881
+					$h = $f*1.3;
5882
+					$prop['value'] = $param['value'];
5883
+					$this->pdf->TextField($name, $w, $h, $prop, array(), $x, $y);
5884
+					break;
5885
+
5886
+				case 'submit':
5887
+					$w = $this->parsingCss->value['width'];    if (!$w) $w = 40;
5888
+					$h = $this->parsingCss->value['height'];    if (!$h) $h = $f*1.3;
5889
+					$action = array('S'=>'SubmitForm', 'F'=>$this->_isInForm, 'Flags'=>array('ExportFormat'));
5890
+					$this->pdf->Button($name, $w, $h, $param['value'], $action, $prop, array(), $x, $y);
5891
+					break;
5892
+
5893
+				case 'reset':
5894
+					$w = $this->parsingCss->value['width'];    if (!$w) $w = 40;
5895
+					$h = $this->parsingCss->value['height'];    if (!$h) $h = $f*1.3;
5896
+					$action = array('S'=>'ResetForm');
5897
+					$this->pdf->Button($name, $w, $h, $param['value'], $action, $prop, array(), $x, $y);
5898
+					break;
5899
+
5900
+				case 'button':
5901
+					$w = $this->parsingCss->value['width'];    if (!$w) $w = 40;
5902
+					$h = $this->parsingCss->value['height'];    if (!$h) $h = $f*1.3;
5903
+					$action = isset($param['onclick']) ? $param['onclick'] : '';
5904
+					$this->pdf->Button($name, $w, $h, $param['value'], $action, $prop, array(), $x, $y);
5905
+					break;
5906
+
5907
+				default:
5908
+					$w = 0;
5909
+					$h = 0;
5910
+					break;
5911
+			}
5912
+
5913
+			$this->_maxX = max($this->_maxX, $x+$w);
5914
+			$this->_maxY = max($this->_maxY, $y+$h);
5915
+			$this->_maxH = max($this->_maxH, $h);
5916
+			$this->_maxE++;
5917
+			$this->pdf->setX($x+$w);
5918
+
5919
+			$this->parsingCss->load();
5920
+			$this->parsingCss->fontSet();
5921
+
5922
+			return true;
5923
+		}
5924
+
5925
+		/**
5926
+		 * tag : DRAW
5927
+		 * mode : OPEN
5928
+		 *
5929
+		 * @param  array $param
5930
+		 * @return boolean
5931
+		 */
5932
+		protected function _tag_open_DRAW($param)
5933
+		{
5934
+			if ($this->_isForOneLine) return false;
5935
+			if ($this->_debugActif) $this->_DEBUG_add('DRAW', true);
5936
+
5937
+			$this->parsingCss->save();
5938
+			$this->parsingCss->analyse('draw', $param);
5939
+			$this->parsingCss->fontSet();
5940
+
5941
+			$alignObject = null;
5942
+			if ($this->parsingCss->value['margin-auto']) $alignObject = 'center';
5943
+
5944
+			$overW = $this->parsingCss->value['width'];
5945
+			$overH = $this->parsingCss->value['height'];
5946
+			$this->parsingCss->value['old_maxX'] = $this->_maxX;
5947
+			$this->parsingCss->value['old_maxY'] = $this->_maxY;
5948
+			$this->parsingCss->value['old_maxH'] = $this->_maxH;
5949
+
5950
+			$w = $this->parsingCss->value['width'];
5951
+			$h = $this->parsingCss->value['height'];
5952
+
5953
+			if (!$this->parsingCss->value['position']) {
5954
+				if (
5955
+					$w < ($this->pdf->getW() - $this->pdf->getlMargin()-$this->pdf->getrMargin()) &&
5956
+					$this->pdf->getX() + $w>=($this->pdf->getW() - $this->pdf->getrMargin())
5957
+					)
5958
+					$this->_tag_open_BR(array());
5959
+
5960
+				if (
5961
+						($h < ($this->pdf->getH() - $this->pdf->gettMargin()-$this->pdf->getbMargin())) &&
5962
+						($this->pdf->getY() + $h>=($this->pdf->getH() - $this->pdf->getbMargin())) &&
5963
+						!$this->_isInOverflow
5964
+					)
5965
+					$this->_setNewPage();
5966
+
5967
+				$old = $this->parsingCss->getOldValues();
5968
+				$parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
5969
+
5970
+				if ($parentWidth>$w) {
5971
+					if ($alignObject=='center')        $this->pdf->setX($this->pdf->getX() + ($parentWidth-$w)*0.5);
5972
+					else if ($alignObject=='right')    $this->pdf->setX($this->pdf->getX() + $parentWidth-$w);
5973
+				}
5974
+
5975
+				$this->parsingCss->setPosition();
5976
+			} else {
5977
+				$old = $this->parsingCss->getOldValues();
5978
+				$parentWidth = $old['width'] ? $old['width'] : $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
5979
+
5980
+				if ($parentWidth>$w) {
5981
+					if ($alignObject=='center')        $this->pdf->setX($this->pdf->getX() + ($parentWidth-$w)*0.5);
5982
+					else if ($alignObject=='right')    $this->pdf->setX($this->pdf->getX() + $parentWidth-$w);
5983
+				}
5984
+
5985
+				$this->parsingCss->setPosition();
5986
+				$this->_saveMax();
5987
+				$this->_maxX = 0;
5988
+				$this->_maxY = 0;
5989
+				$this->_maxH = 0;
5990
+				$this->_maxE = 0;
5991
+			}
5992
+
5993
+			$this->_drawRectangle(
5994
+				$this->parsingCss->value['x'],
5995
+				$this->parsingCss->value['y'],
5996
+				$this->parsingCss->value['width'],
5997
+				$this->parsingCss->value['height'],
5998
+				$this->parsingCss->value['border'],
5999
+				$this->parsingCss->value['padding'],
6000
+				0,
6001
+				$this->parsingCss->value['background']
6002
+			);
6003
+
6004
+			$marge = array();
6005
+			$marge['l'] = $this->parsingCss->value['border']['l']['width'];
6006
+			$marge['r'] = $this->parsingCss->value['border']['r']['width'];
6007
+			$marge['t'] = $this->parsingCss->value['border']['t']['width'];
6008
+			$marge['b'] = $this->parsingCss->value['border']['b']['width'];
6009
+
6010
+			$this->parsingCss->value['width'] -= $marge['l']+$marge['r'];
6011
+			$this->parsingCss->value['height']-= $marge['t']+$marge['b'];
6012
+
6013
+			$overW-= $marge['l']+$marge['r'];
6014
+			$overH-= $marge['t']+$marge['b'];
6015
+
6016
+			// clipping to draw only in the size opf the DRAW tag
6017
+			$this->pdf->clippingPathStart(
6018
+				$this->parsingCss->value['x']+$marge['l'],
6019
+				$this->parsingCss->value['y']+$marge['t'],
6020
+				$this->parsingCss->value['width'],
6021
+				$this->parsingCss->value['height']
6022
+			);
6023
+
6024
+			// left and right of the DRAW tag
6025
+			$mL = $this->parsingCss->value['x']+$marge['l'];
6026
+			$mR = $this->pdf->getW() - $mL - $overW;
6027
+
6028
+			// position of the DRAW tag
6029
+			$x = $this->parsingCss->value['x']+$marge['l'];
6030
+			$y = $this->parsingCss->value['y']+$marge['t'];
6031
+
6032
+			// prepare the drawing area
6033
+			$this->_saveMargin($mL, 0, $mR);
6034
+			$this->pdf->setXY($x, $y);
6035
+
6036
+			// we are in a draw tag
6037
+			$this->_isInDraw = array(
6038
+				'x' => $x,
6039
+				'y' => $y,
6040
+				'w' => $overW,
6041
+				'h' => $overH,
6042
+			);
6043
+
6044
+			// init the translate matrix : (0,0) => ($x, $y)
6045
+			$this->pdf->doTransform(array(1,0,0,1,$x,$y));
6046
+			$this->pdf->SetAlpha(1.);
6047
+			return true;
6048
+		}
6049
+
6050
+		/**
6051
+		 * tag : DRAW
6052
+		 * mode : CLOSE
6053
+		 *
6054
+		 * @param  array $param
6055
+		 * @return boolean
6056
+		 */
6057
+		protected function _tag_close_DRAW($param)
6058
+		{
6059
+			if ($this->_isForOneLine) return false;
6060
+
6061
+			$this->pdf->SetAlpha(1.);
6062
+			$this->pdf->undoTransform();
6063
+			$this->pdf->clippingPathStop();
6064
+
6065
+			$this->_maxX = $this->parsingCss->value['old_maxX'];
6066
+			$this->_maxY = $this->parsingCss->value['old_maxY'];
6067
+			$this->_maxH = $this->parsingCss->value['old_maxH'];
6068
+
6069
+			$marge = array();
6070
+			$marge['l'] = $this->parsingCss->value['border']['l']['width'];
6071
+			$marge['r'] = $this->parsingCss->value['border']['r']['width'];
6072
+			$marge['t'] = $this->parsingCss->value['border']['t']['width'];
6073
+			$marge['b'] = $this->parsingCss->value['border']['b']['width'];
6074
+
6075
+			$x = $this->parsingCss->value['x'];
6076
+			$y = $this->parsingCss->value['y'];
6077
+			$w = $this->parsingCss->value['width']+$marge['l']+$marge['r'];
6078
+			$h = $this->parsingCss->value['height']+$marge['t']+$marge['b'];
6079
+
6080
+			if ($this->parsingCss->value['position']!='absolute') {
6081
+				$this->pdf->setXY($x+$w, $y);
6082
+
6083
+				$this->_maxX = max($this->_maxX, $x+$w);
6084
+				$this->_maxY = max($this->_maxY, $y+$h);
6085
+				$this->_maxH = max($this->_maxH, $h);
6086
+				$this->_maxE++;
6087
+			} else {
6088
+				// position
6089
+				$this->pdf->setXY($this->parsingCss->value['xc'], $this->parsingCss->value['yc']);
6090
+
6091
+				$this->_loadMax();
6092
+			}
6093
+
6094
+			$block = ($this->parsingCss->value['display']!='inline' && $this->parsingCss->value['position']!='absolute');
6095
+
6096
+			$this->parsingCss->load();
6097
+			$this->parsingCss->fontSet();
6098
+			$this->_loadMargin();
6099
+
6100
+			if ($block) $this->_tag_open_BR(array());
6101
+			if ($this->_debugActif) $this->_DEBUG_add('DRAW', false);
6102
+
6103
+			$this->_isInDraw = null;
6104
+
6105
+			return true;
6106
+		}
6107
+
6108
+		/**
6109
+		 * tag : LINE
6110
+		 * mode : OPEN
6111
+		 *
6112
+		 * @param  array $param
6113
+		 * @return boolean
6114
+		 */
6115
+		protected function _tag_open_LINE($param)
6116
+		{
6117
+			if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'LINE');
6118
+
6119
+			$this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6120
+			$this->parsingCss->save();
6121
+			$styles = $this->parsingCss->getSvgStyle('path', $param);
6122
+			$styles['fill'] = null;
6123
+			$style = $this->pdf->svgSetStyle($styles);
6124
+
6125
+			$x1 = isset($param['x1']) ? $this->parsingCss->ConvertToMM($param['x1'], $this->_isInDraw['w']) : 0.;
6126
+			$y1 = isset($param['y1']) ? $this->parsingCss->ConvertToMM($param['y1'], $this->_isInDraw['h']) : 0.;
6127
+			$x2 = isset($param['x2']) ? $this->parsingCss->ConvertToMM($param['x2'], $this->_isInDraw['w']) : 0.;
6128
+			$y2 = isset($param['y2']) ? $this->parsingCss->ConvertToMM($param['y2'], $this->_isInDraw['h']) : 0.;
6129
+			$this->pdf->svgLine($x1, $y1, $x2, $y2);
6130
+
6131
+			$this->pdf->undoTransform();
6132
+			$this->parsingCss->load();
6133
+		}
6134
+
6135
+		/**
6136
+		 * tag : RECT
6137
+		 * mode : OPEN
6138
+		 *
6139
+		 * @param  array $param
6140
+		 * @return boolean
6141
+		 */
6142
+		protected function _tag_open_RECT($param)
6143
+		{
6144
+			if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'RECT');
6145
+
6146
+			$this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6147
+			$this->parsingCss->save();
6148
+			$styles = $this->parsingCss->getSvgStyle('path', $param);
6149
+			$style = $this->pdf->svgSetStyle($styles);
6150
+
6151
+			$x = isset($param['x']) ? $this->parsingCss->ConvertToMM($param['x'], $this->_isInDraw['w']) : 0.;
6152
+			$y = isset($param['y']) ? $this->parsingCss->ConvertToMM($param['y'], $this->_isInDraw['h']) : 0.;
6153
+			$w = isset($param['w']) ? $this->parsingCss->ConvertToMM($param['w'], $this->_isInDraw['w']) : 0.;
6154
+			$h = isset($param['h']) ? $this->parsingCss->ConvertToMM($param['h'], $this->_isInDraw['h']) : 0.;
6155
+
6156
+			$this->pdf->svgRect($x, $y, $w, $h, $style);
6157
+
6158
+			$this->pdf->undoTransform();
6159
+			$this->parsingCss->load();
6160
+		}
6161
+
6162
+		/**
6163
+		 * tag : CIRCLE
6164
+		 * mode : OPEN
6165
+		 *
6166
+		 * @param  array $param
6167
+		 * @return boolean
6168
+		 */
6169
+		protected function _tag_open_CIRCLE($param)
6170
+		{
6171
+			if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'CIRCLE');
6172
+
6173
+			$this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6174
+			$this->parsingCss->save();
6175
+			$styles = $this->parsingCss->getSvgStyle('path', $param);
6176
+			$style = $this->pdf->svgSetStyle($styles);
6177
+
6178
+			$cx = isset($param['cx']) ? $this->parsingCss->ConvertToMM($param['cx'], $this->_isInDraw['w']) : 0.;
6179
+			$cy = isset($param['cy']) ? $this->parsingCss->ConvertToMM($param['cy'], $this->_isInDraw['h']) : 0.;
6180
+			$r = isset($param['r']) ? $this->parsingCss->ConvertToMM($param['r'], $this->_isInDraw['w']) : 0.;
6181
+			$this->pdf->svgEllipse($cx, $cy, $r, $r, $style);
6182
+
6183
+			$this->pdf->undoTransform();
6184
+			$this->parsingCss->load();
6185
+		}
6186
+
6187
+		/**
6188
+		 * tag : ELLIPSE
6189
+		 * mode : OPEN
6190
+		 *
6191
+		 * @param  array $param
6192
+		 * @return boolean
6193
+		 */
6194
+		protected function _tag_open_ELLIPSE($param)
6195
+		{
6196
+			if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'ELLIPSE');
6197
+
6198
+			$this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6199
+			$this->parsingCss->save();
6200
+			$styles = $this->parsingCss->getSvgStyle('path', $param);
6201
+			$style = $this->pdf->svgSetStyle($styles);
6202
+
6203
+			$cx = isset($param['cx']) ? $this->parsingCss->ConvertToMM($param['cx'], $this->_isInDraw['w']) : 0.;
6204
+			$cy = isset($param['cy']) ? $this->parsingCss->ConvertToMM($param['cy'], $this->_isInDraw['h']) : 0.;
6205
+			$rx = isset($param['ry']) ? $this->parsingCss->ConvertToMM($param['rx'], $this->_isInDraw['w']) : 0.;
6206
+			$ry = isset($param['rx']) ? $this->parsingCss->ConvertToMM($param['ry'], $this->_isInDraw['h']) : 0.;
6207
+			$this->pdf->svgEllipse($cx, $cy, $rx, $ry, $style);
6208
+
6209
+			$this->pdf->undoTransform();
6210
+			$this->parsingCss->load();
6211
+		}
6212
+
6213
+
6214
+		/**
6215
+		 * tag : POLYLINE
6216
+		 * mode : OPEN
6217
+		 *
6218
+		 * @param  array $param
6219
+		 * @return boolean
6220
+		 */
6221
+		protected function _tag_open_POLYLINE($param)
6222
+		{
6223
+			if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'POLYGON');
6224
+
6225
+			$this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6226
+			$this->parsingCss->save();
6227
+			$styles = $this->parsingCss->getSvgStyle('path', $param);
6228
+			$style = $this->pdf->svgSetStyle($styles);
6229
+
6230
+			$path = isset($param['points']) ? $param['points'] : null;
6231
+			if ($path) {
6232
+				$path = str_replace(',', ' ', $path);
6233
+				$path = preg_replace('/[\s]+/', ' ', trim($path));
6234
+
6235
+				// prepare the path
6236
+				$path = explode(' ', $path);
6237
+				foreach ($path as $k => $v) {
6238
+					$path[$k] = trim($v);
6239
+					if ($path[$k]==='') unset($path[$k]);
6240
+				}
6241
+				$path = array_values($path);
6242
+
6243
+				$actions = array();
6244
+				for ($k=0; $k<count($path); $k+=2) {
6245
+					$actions[] = array(
6246
+						($k ? 'L' : 'M') ,
6247
+						$this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']),
6248
+						$this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h'])
6249
+					);
6250
+				}
6251
+
6252
+				// drawing
6253
+				$this->pdf->svgPolygone($actions, $style);
6254
+			}
6255
+
6256
+			$this->pdf->undoTransform();
6257
+			$this->parsingCss->load();
6258
+		}
6259
+
6260
+		/**
6261
+		 * tag : POLYGON
6262
+		 * mode : OPEN
6263
+		 *
6264
+		 * @param  array $param
6265
+		 * @return boolean
6266
+		 */
6267
+		protected function _tag_open_POLYGON($param)
6268
+		{
6269
+			if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'POLYGON');
6270
+
6271
+			$this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6272
+			$this->parsingCss->save();
6273
+			$styles = $this->parsingCss->getSvgStyle('path', $param);
6274
+			$style = $this->pdf->svgSetStyle($styles);
6275
+
6276
+			$path = (isset($param['points']) ? $param['points'] : null);
6277
+			if ($path) {
6278
+				$path = str_replace(',', ' ', $path);
6279
+				$path = preg_replace('/[\s]+/', ' ', trim($path));
6280
+
6281
+				// prepare the path
6282
+				$path = explode(' ', $path);
6283
+				foreach ($path as $k => $v) {
6284
+					$path[$k] = trim($v);
6285
+					if ($path[$k]==='') unset($path[$k]);
6286
+				}
6287
+				$path = array_values($path);
6288
+
6289
+				$actions = array();
6290
+				for ($k=0; $k<count($path); $k+=2) {
6291
+					$actions[] = array(
6292
+						($k ? 'L' : 'M') ,
6293
+						$this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']),
6294
+						$this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h'])
6295
+					);
6296
+				}
6297
+				$actions[] = array('z');
6298
+
6299
+				// drawing
6300
+				$this->pdf->svgPolygone($actions, $style);
6301
+			}
6302
+
6303
+			$this->pdf->undoTransform();
6304
+			$this->parsingCss->load();
6305
+		}
6306
+
6307
+		/**
6308
+		 * tag : PATH
6309
+		 * mode : OPEN
6310
+		 *
6311
+		 * @param  array $param
6312
+		 * @return boolean
6313
+		 */
6314
+		protected function _tag_open_PATH($param)
6315
+		{
6316
+			if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'PATH');
6317
+
6318
+			$this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6319
+			$this->parsingCss->save();
6320
+			$styles = $this->parsingCss->getSvgStyle('path', $param);
6321
+			$style = $this->pdf->svgSetStyle($styles);
6322
+
6323
+			$path = isset($param['d']) ? $param['d'] : null;
6324
+
6325
+			if ($path) {
6326
+				// prepare the path
6327
+				$path = str_replace(',', ' ', $path);
6328
+				$path = preg_replace('/([a-zA-Z])([0-9\.\-])/', '$1 $2', $path);
6329
+				$path = preg_replace('/([0-9\.])([a-zA-Z])/', '$1 $2', $path);
6330
+				$path = preg_replace('/[\s]+/', ' ', trim($path));
6331
+				$path = preg_replace('/ ([a-z]{2})/', '$1', $path);
6332
+
6333
+				$path = explode(' ', $path);
6334
+				foreach ($path as $k => $v) {
6335
+					$path[$k] = trim($v);
6336
+					if ($path[$k]==='') unset($path[$k]);
6337
+				}
6338
+				$path = array_values($path);
6339
+
6340
+				// read each actions in the path
6341
+				$actions = array();
6342
+				$action = array();
6343
+				$lastAction = null; // last action found
6344
+				for ($k=0; $k<count($path);true) {
6345
+
6346
+					// for this actions, we can not have multi coordonate
6347
+					if (in_array($lastAction, array('z', 'Z'))) {
6348
+						$lastAction = null;
6349
+					}
6350
+
6351
+					// read the new action (forcing if no action before)
6352
+					if (preg_match('/^[a-z]+$/i', $path[$k]) || $lastAction===null) {
6353
+						$lastAction = $path[$k];
6354
+						$k++;
6355
+					}
6356
+
6357
+					// current action
6358
+					$action = array();
6359
+					$action[] = $lastAction;
6360
+					switch($lastAction)
6361
+					{
6362
+						case 'C':
6363
+						case 'c':
6364
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // x1
6365
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h']);    // y1
6366
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+2], $this->_isInDraw['w']);    // x2
6367
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+3], $this->_isInDraw['h']);    // y2
6368
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+4], $this->_isInDraw['w']);    // x
6369
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+5], $this->_isInDraw['h']);    // y
6370
+							$k+= 6;
6371
+							break;
6372
+
6373
+						case 'Q':
6374
+						case 'S':
6375
+						case 'q':
6376
+						case 's':
6377
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // x2
6378
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h']);    // y2
6379
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+2], $this->_isInDraw['w']);    // x
6380
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+3], $this->_isInDraw['h']);    // y
6381
+							$k+= 4;
6382
+							break;
6383
+
6384
+						case 'A':
6385
+						case 'a':
6386
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // rx
6387
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h']);    // ry
6388
+							$action[] = 1.*$path[$k+2];                                                        // angle de deviation de l'axe X
6389
+							$action[] = ($path[$k+3]=='1') ? 1 : 0;                                            // large-arc-flag
6390
+							$action[] = ($path[$k+4]=='1') ? 1 : 0;                                            // sweep-flag
6391
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+5], $this->_isInDraw['w']);    // x
6392
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+6], $this->_isInDraw['h']);    // y
6393
+							$k+= 7;
6394
+							break;
6395
+
6396
+						case 'M':
6397
+						case 'L':
6398
+						case 'T':
6399
+						case 'm':
6400
+						case 'l':
6401
+						case 't':
6402
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // x
6403
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+1], $this->_isInDraw['h']);    // y
6404
+							$k+= 2;
6405
+							break;
6406
+
6407
+						case 'H':
6408
+						case 'h':
6409
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['w']);    // x
6410
+							$k+= 1;
6411
+							break;
6412
+
6413
+						case 'V':
6414
+						case 'v':
6415
+							$action[] = $this->parsingCss->ConvertToMM($path[$k+0], $this->_isInDraw['h']);    // y
6416
+							$k+= 1;
6417
+							break;
6418
+
6419
+						case 'z':
6420
+						case 'Z':
6421
+						default:
6422
+							break;
6423
+					}
6424
+					// add the action
6425
+					$actions[] = $action;
6426
+				}
6427
+
6428
+				// drawing
6429
+				$this->pdf->svgPolygone($actions, $style);
6430
+			}
6431
+
6432
+			$this->pdf->undoTransform();
6433
+			$this->parsingCss->load();
6434
+		}
6435
+
6436
+		/**
6437
+		 * tag : G
6438
+		 * mode : OPEN
6439
+		 *
6440
+		 * @param  array $param
6441
+		 * @return boolean
6442
+		 */
6443
+		protected function _tag_open_G($param)
6444
+		{
6445
+			if (!$this->_isInDraw) throw new HTML2PDF_exception(8, 'G');
6446
+
6447
+			$this->pdf->doTransform(isset($param['transform']) ? $this->_prepareTransform($param['transform']) : null);
6448
+			$this->parsingCss->save();
6449
+			$styles = $this->parsingCss->getSvgStyle('path', $param);
6450
+			$style = $this->pdf->svgSetStyle($styles);
6451
+		}
6452
+
6453
+		/**
6454
+		 * tag : G
6455
+		 * mode : CLOSE
6456
+		 *
6457
+		 * @param  array $param
6458
+		 * @return boolean
6459
+		 */
6460
+		protected function _tag_close_G($param)
6461
+		{
6462
+			$this->pdf->undoTransform();
6463
+			$this->parsingCss->load();
6464
+		}
6465
+
6466
+		/**
6467
+		 * new page for the automatic Index, does not use thie method. Only HTML2PDF_myPdf could use it !!!!
6468
+		 *
6469
+		 * @param  &int $page
6470
+		 * @return integer $oldPage
6471
+		 */
6472
+		public function _INDEX_NewPage(&$page)
6473
+		{
6474
+			if ($page) {
6475
+				$oldPage = $this->pdf->getPage();
6476
+				$this->pdf->setPage($page);
6477
+				$this->pdf->setXY($this->_margeLeft, $this->_margeTop);
6478
+				$this->_maxH = 0;
6479
+				$page++;
6480
+				return $oldPage;
6481
+			} else {
6482
+				$this->_setNewPage();
6483
+				return null;
6484
+			}
6485
+		}
6486
+
6487
+	}
6489 6488
 }
Please login to merge, or discard this patch.
web_interface/astpp/application/libraries/global_locale.php 1 patch
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -22,16 +22,16 @@  discard block
 block discarded – undo
22 22
 ###############################################################################
23 23
 
24 24
 if (!defined('BASEPATH'))
25
-    exit('No direct script access allowed');
25
+	exit('No direct script access allowed');
26 26
 
27 27
 /**
28 28
  * Dynamically build forms for display
29 29
  */
30 30
 class Global_locale{
31 31
 
32
-    function __construct($library_name = '') {
32
+	function __construct($library_name = '') {
33 33
 
34
-        $this->CI = & get_instance();
34
+		$this->CI = & get_instance();
35 35
 	header("Expires: Tue, 01 Jan 2000 00:00:00 GMT");
36 36
 	header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
37 37
 	header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
@@ -42,7 +42,7 @@  discard block
 block discarded – undo
42 42
 	
43 43
 	
44 44
 	
45
-    }
45
+	}
46 46
     
47 47
     
48 48
  }
Please login to merge, or discard this patch.
web_interface/astpp/application/libraries/locale_menu.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -22,26 +22,26 @@
 block discarded – undo
22 22
 ###############################################################################
23 23
 
24 24
 if (!defined('BASEPATH'))
25
-    exit('No direct script access allowed');
25
+	exit('No direct script access allowed');
26 26
 
27 27
 /**
28 28
  * Dynamically build forms for display
29 29
  */
30 30
 class locale_Menu{
31 31
 
32
-    function __construct($library_name = '') {
32
+	function __construct($library_name = '') {
33 33
 
34
-        $this->CI = & get_instance();
35
-        $this->CI->load->model('db_model');
36
-        $this->CI->load->library('email');
37
-        $this->CI->load->library('session');
34
+		$this->CI = & get_instance();
35
+		$this->CI->load->model('db_model');
36
+		$this->CI->load->library('email');
37
+		$this->CI->load->library('session');
38 38
 	$current_locale=$this->CI->session->userdata('user_language');
39 39
 	putenv("LC_ALL=$current_locale");
40 40
 	setlocale(LC_ALL, $current_locale); 
41 41
 	bindtextdomain(WEBSITE_DOMAIN, FCPATH.'/application/modules/dashboard/language');
42 42
 	bind_textdomain_codeset(WEBSITE_DOMAIN, 'UTF-8');
43 43
 	textdomain(WEBSITE_DOMAIN);
44
-    }
44
+	}
45 45
     
46 46
     
47 47
  }
Please login to merge, or discard this patch.
web_interface/astpp/application/libraries/locale.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -22,43 +22,43 @@
 block discarded – undo
22 22
 ###############################################################################
23 23
 
24 24
 if (!defined('BASEPATH'))
25
-    exit('No direct script access allowed');
25
+	exit('No direct script access allowed');
26 26
 
27 27
 /**
28 28
  * Dynamically build forms for display
29 29
  */
30 30
 class Locale{
31 31
 
32
-    function __construct($library_name = '') {
32
+	function __construct($library_name = '') {
33 33
 
34
-        $this->CI = & get_instance();
35
-        $this->CI->load->model('db_model');
36
-        $this->CI->load->library('email');
37
-        $this->CI->load->library('session');
38
-        $this->CI->load->driver('cache');
34
+		$this->CI = & get_instance();
35
+		$this->CI->load->model('db_model');
36
+		$this->CI->load->library('email');
37
+		$this->CI->load->library('session');
38
+		$this->CI->load->driver('cache');
39 39
 	$this->set_lang();
40
-    }
41
-    function set_lang($lang=FALSE){
40
+	}
41
+	function set_lang($lang=FALSE){
42 42
 
43
-        $current_locale=$this->CI->session->userdata('user_language');
44
-        if(empty($current_locale)){
45
-             $current_locale= 'en_US';
46
-        }
43
+		$current_locale=$this->CI->session->userdata('user_language');
44
+		if(empty($current_locale)){
45
+			 $current_locale= 'en_US';
46
+		}
47 47
 	putenv("LANG=$current_locale");
48 48
 	setlocale(LC_ALL, $current_locale.".UTF-8");
49
-        setlocale(LC_MESSAGES,$current_locale);
49
+		setlocale(LC_MESSAGES,$current_locale);
50 50
 	setlocale(LC_TIME, $current_locale);
51
-        setlocale(LC_CTYPE,$current_locale);
51
+		setlocale(LC_CTYPE,$current_locale);
52 52
 	$domain='messages';
53 53
 	$uri_segment='';
54 54
 	 $uri_segment = $this->CI->uri->segments;
55 55
 	if(isset($uri_segment[1])){	
56 56
 		$filename = getcwd().'/application/modules/user/language/'.$lang.'/LC_MESSAGES/messages.mo';
57
-                bindtextdomain(WEBSITE_DOMAIN,getcwd().'/application/modules/'.$uri_segment[1].'/language/');
57
+				bindtextdomain(WEBSITE_DOMAIN,getcwd().'/application/modules/'.$uri_segment[1].'/language/');
58 58
 	}
59 59
 	bind_textdomain_codeset(WEBSITE_DOMAIN, 'UTF-8');
60 60
 	textdomain(WEBSITE_DOMAIN);
61
-         return true;
61
+		 return true;
62 62
 	}
63 63
 }
64 64
 
Please login to merge, or discard this patch.
web_interface/astpp/application/libraries/freeswitch_lib.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -25,29 +25,29 @@  discard block
 block discarded – undo
25 25
 class freeswitch_lib{
26 26
 	
27 27
 	function event_socket_create($host='127.0.0.1', $port='8021', $password='ClueCon') {
28
-	    $fp = @fsockopen($host, $port, $errno, $errdesc);
28
+		$fp = @fsockopen($host, $port, $errno, $errdesc);
29 29
 // 	    or die("Connection to $host failed");
30 30
 // 	    socket_set_blocking($fp,false);
31 31
 	    
32
-	    if ($fp) {
32
+		if ($fp) {
33 33
 		socket_set_blocking($fp,false);
34 34
 		while (!feof($fp)) {
35
-		    $buffer = fgets($fp, 1024);
36
-		    usleep(100); //allow time for reponse
37
-		    if (trim($buffer) == "Content-Type: auth/request") {
38
-		      fputs($fp, "auth $password\n\n");
39
-		      break;
40
-		    }
35
+			$buffer = fgets($fp, 1024);
36
+			usleep(100); //allow time for reponse
37
+			if (trim($buffer) == "Content-Type: auth/request") {
38
+			  fputs($fp, "auth $password\n\n");
39
+			  break;
40
+			}
41 41
 		}
42 42
 		return $fp;
43
-	    }
44
-	    else {
43
+		}
44
+		else {
45 45
 		return false;
46
-	    }           
46
+		}           
47 47
 	}
48 48
 
49 49
 	function event_socket_request($fp, $cmd) {
50
-	    if ($fp) {    
50
+		if ($fp) {    
51 51
 		fputs($fp, $cmd."\n\n");    
52 52
 		usleep(100); //allow time for reponse
53 53
 		
@@ -55,39 +55,39 @@  discard block
 block discarded – undo
55 55
 		$i = 0;
56 56
 		$contentlength = 0;
57 57
 		while (!feof($fp)) {
58
-		    $buffer = fgets($fp, 4096);
59
-		    if ($contentlength > 0) {
60
-		      $response .= $buffer;
61
-		    }
58
+			$buffer = fgets($fp, 4096);
59
+			if ($contentlength > 0) {
60
+			  $response .= $buffer;
61
+			}
62 62
 		    
63
-		    if ($contentlength == 0) { //if contentlenght is already don't process again
63
+			if ($contentlength == 0) { //if contentlenght is already don't process again
64 64
 			if (strlen(trim($buffer)) > 0) { //run only if buffer has content
65
-			    $temparray = explode(":", trim($buffer));
66
-			    if ($temparray[0] == "Content-Length") {
67
-			      $contentlength = trim($temparray[1]);
68
-			    }
65
+				$temparray = explode(":", trim($buffer));
66
+				if ($temparray[0] == "Content-Length") {
67
+				  $contentlength = trim($temparray[1]);
68
+				}
69
+			}
69 70
 			}
70
-		    }
71 71
 		    
72
-		    usleep(100); //allow time for reponse
72
+			usleep(100); //allow time for reponse
73 73
 		    
74
-		    //optional because of script timeout //don't let while loop become endless
75
-		    if ($i > 10000) { break; } 
74
+			//optional because of script timeout //don't let while loop become endless
75
+			if ($i > 10000) { break; } 
76 76
 		    
77
-		    if ($contentlength > 0) { //is contentlength set
77
+			if ($contentlength > 0) { //is contentlength set
78 78
 			//stop reading if all content has been read.
79 79
 			if (strlen($response) >= $contentlength) {  
80 80
 			  break;
81 81
 			}
82
-		    }
83
-		    $i++;
82
+			}
83
+			$i++;
84 84
 		}
85 85
 				
86 86
 		return $response;
87
-	    }
88
-	    else {
87
+		}
88
+		else {
89 89
 // 	      echo "no handle";
90
-	    }
90
+		}
91 91
 	}
92 92
 }
93 93
 ?>
Please login to merge, or discard this patch.
web_interface/astpp/application/config/constants.php 1 patch
Indentation   +60 added lines, -60 removed lines patch added patch discarded remove patch
@@ -37,74 +37,74 @@
 block discarded – undo
37 37
 define('FOPEN_READ_WRITE_CREATE_STRICT',		'x+b');
38 38
 define("RESELLERPROFILE_ARRAY",  serialize(array(
39 39
 				"My Profile"=>"user/user_myprofile/",
40
-                                "Change Password"=>"user/user_change_password/",
41
-                                "Subscriptions"=>"user/user_subscriptions/",
42
-                                "Invoice"=>"user/user_invoices_list/",
43
-                                "Refill Report"=>"user/user_refill_report/",
44
-                                "Charges History"=>"user/user_charges_history/",
45
-                                "Packages"=>"user/user_packages/",
46
-                                "Company Profile"=>"user/user_invoice_config/",
47
-                                "CDRs"=>"user/user_cdrs/",
48
-                                "Emails"=>"user/user_emails/",
49
-                                "Alert Threshold"=>"user/user_alert_threshold/"
50
-                               ))
40
+								"Change Password"=>"user/user_change_password/",
41
+								"Subscriptions"=>"user/user_subscriptions/",
42
+								"Invoice"=>"user/user_invoices_list/",
43
+								"Refill Report"=>"user/user_refill_report/",
44
+								"Charges History"=>"user/user_charges_history/",
45
+								"Packages"=>"user/user_packages/",
46
+								"Company Profile"=>"user/user_invoice_config/",
47
+								"CDRs"=>"user/user_cdrs/",
48
+								"Emails"=>"user/user_emails/",
49
+								"Alert Threshold"=>"user/user_alert_threshold/"
50
+							   ))
51 51
 );
52 52
 define("CUSTOMEREDIT_ARRAY",serialize(array(
53
-                                              "Customer Profile"=>"accounts/customer_edit/",
54
-                                              "SIP Devices"=>"accounts/customer_sipdevices/",
55
-                                              "Opensips Device"=>"accounts/customer_opensips/",
56
-                                              "IP Settings"=>"accounts/customer_ipmap/",
57
-                                              "Caller ID"=>"accounts/customer_animap/",
58
-                                              "Speed Dial"=>"accounts/customer_speeddial/",
59
-                                              "Blocked Codes"=>"accounts/customer_blocked_prefixes/",
60
-                                              "DID"=>"accounts/customer_dids/",
61
-                                              "Subscription"=>"accounts/customer_subscription/",
62
-                                              "Invoice"=>"accounts/customer_invoices/",
63
-                                              "Refill Report"=>"accounts/customer_refillreport/",
64
-                                              "Charges History"=>"accounts/customer_charges/",
65
-                                              "CDRs"=>"accounts/customer_cdrs/",
66
-                                              "Emails"=>"accounts/customer_emailhistory/",
67
-                                              "Alert Threshold"=>"accounts/customer_alert_threshold/"
68
-                                             )
69
-                              ));
53
+											  "Customer Profile"=>"accounts/customer_edit/",
54
+											  "SIP Devices"=>"accounts/customer_sipdevices/",
55
+											  "Opensips Device"=>"accounts/customer_opensips/",
56
+											  "IP Settings"=>"accounts/customer_ipmap/",
57
+											  "Caller ID"=>"accounts/customer_animap/",
58
+											  "Speed Dial"=>"accounts/customer_speeddial/",
59
+											  "Blocked Codes"=>"accounts/customer_blocked_prefixes/",
60
+											  "DID"=>"accounts/customer_dids/",
61
+											  "Subscription"=>"accounts/customer_subscription/",
62
+											  "Invoice"=>"accounts/customer_invoices/",
63
+											  "Refill Report"=>"accounts/customer_refillreport/",
64
+											  "Charges History"=>"accounts/customer_charges/",
65
+											  "CDRs"=>"accounts/customer_cdrs/",
66
+											  "Emails"=>"accounts/customer_emailhistory/",
67
+											  "Alert Threshold"=>"accounts/customer_alert_threshold/"
68
+											 )
69
+							  ));
70 70
 
71 71
 define("PROVIDEREDIT_ARRAY",serialize(array(
72
-					      "Provider Profile"=>"accounts/provider_edit/",
73
-                                              "SIP Devices"=>"accounts/provider_sipdevices/",
74
-                                              "Opensips Device"=>"accounts/provider_opensips/",
75
-                                              "IP Settings"=>"accounts/provider_ipmap/",
76
-                                              "Caller ID"=>"accounts/provider_animap/",
77
-                                              "Speed Dial"=>"accounts/provider_speeddial/",
78
-                                              "Blocked Codes"=>"accounts/provider_blocked_prefixes/",
79
-                                              "DID"=>"accounts/provider_dids/",
80
-                                              "Subscription"=>"accounts/provider_subscription/",
81
-                                              "Invoice"=>"accounts/provider_invoices/",
82
-                                              "Refill Report"=>"accounts/provider_refillreport/",
83
-                                              "Charges History"=>"accounts/provider_charges/",
84
-                                              "CDRs"=>"accounts/provider_cdrs/",
85
-                                              "Emails"=>"accounts/provider_emailhistory/",
86
-                                              "Alert Threshold"=>"accounts/provider_alert_threshold/"
87
-                                             )
88
-                              ));
72
+						  "Provider Profile"=>"accounts/provider_edit/",
73
+											  "SIP Devices"=>"accounts/provider_sipdevices/",
74
+											  "Opensips Device"=>"accounts/provider_opensips/",
75
+											  "IP Settings"=>"accounts/provider_ipmap/",
76
+											  "Caller ID"=>"accounts/provider_animap/",
77
+											  "Speed Dial"=>"accounts/provider_speeddial/",
78
+											  "Blocked Codes"=>"accounts/provider_blocked_prefixes/",
79
+											  "DID"=>"accounts/provider_dids/",
80
+											  "Subscription"=>"accounts/provider_subscription/",
81
+											  "Invoice"=>"accounts/provider_invoices/",
82
+											  "Refill Report"=>"accounts/provider_refillreport/",
83
+											  "Charges History"=>"accounts/provider_charges/",
84
+											  "CDRs"=>"accounts/provider_cdrs/",
85
+											  "Emails"=>"accounts/provider_emailhistory/",
86
+											  "Alert Threshold"=>"accounts/provider_alert_threshold/"
87
+											 )
88
+							  ));
89 89
 define("RESELLEREDIT_ARRAY",serialize(array("Reseller Profile"=>"accounts/reseller_edit/",
90
-					    "DID"=>"accounts/reseller_dids/",
91
-                                            "Subscription"=>"accounts/reseller_subscription/",
92
-                                            "Invoice"=>"accounts/reseller_invoices/",
93
-                                            "Refill Report"=>"accounts/reseller_refillreport/",
94
-                                            "Charges History"=>"accounts/reseller_charges/",
95
-                                            "Packages"=>"accounts/reseller_packages/",
96
-                                            "Company Profile"=>"accounts/reseller_invoice_config/",
97
-                                            "CDRs"=>"accounts/reseller_cdrs/",
98
-                                            "Emails"=>"accounts/reseller_emailhistory/",
99
-                                            "Alert Threshold"=>"accounts/reseller_alert_threshold/"
90
+						"DID"=>"accounts/reseller_dids/",
91
+											"Subscription"=>"accounts/reseller_subscription/",
92
+											"Invoice"=>"accounts/reseller_invoices/",
93
+											"Refill Report"=>"accounts/reseller_refillreport/",
94
+											"Charges History"=>"accounts/reseller_charges/",
95
+											"Packages"=>"accounts/reseller_packages/",
96
+											"Company Profile"=>"accounts/reseller_invoice_config/",
97
+											"CDRs"=>"accounts/reseller_cdrs/",
98
+											"Emails"=>"accounts/reseller_emailhistory/",
99
+											"Alert Threshold"=>"accounts/reseller_alert_threshold/"
100 100
 )));
101 101
 define("PACKAGEEDIT_ARRAY",  serialize( array(
102
-                                            "Package Details"=>"package/package_edit/",
103
-                                            "Package Codes"=>"package/package_pattern_list/"
104
-                                       )));
102
+											"Package Details"=>"package/package_edit/",
103
+											"Package Codes"=>"package/package_pattern_list/"
104
+									   )));
105 105
 define("CUSTOMERPROFILE_ARRAY",serialize(array(
106
-            "My Profile"=>"user/user_myprofile/",
107
-            "Change Password"=>"user/user_change_password"
106
+			"My Profile"=>"user/user_myprofile/",
107
+			"Change Password"=>"user/user_change_password"
108 108
 )));
109 109
 define("DATABASE_DIRECTORY",FCPATH.'database_backup'.DIRECTORY_SEPARATOR);
110 110
 define('LOCALE_REQUEST_PARAM', 'lang');
Please login to merge, or discard this patch.
web_interface/astpp/application/config/cron.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -12,7 +12,7 @@
 block discarded – undo
12 12
 $config['argv']			= array("LowBalance"=>"lowbalance/low_balance",
13 13
 					"Lowcredit"=>"lowcreditlimit/low_creditlimit",
14 14
 					"UpdateBalance" => "updateBalance/GetUpdateBalance",
15
-				        "CurrencyUpdate" => "currencyupdate/update_currency",
15
+						"CurrencyUpdate" => "currencyupdate/update_currency",
16 16
 					"GenerateInvoice" => "generateInvoice/getInvoiceData",
17 17
 					"FeedBack"=>"feedback/customer_feedback_result/TRUE",
18 18
 					"BroadcastEmail" => "broadcastemail/broadcast_email");
Please login to merge, or discard this patch.
web_interface/astpp/application/config/config.php 1 patch
Indentation   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 if (!defined('BASEPATH'))
4
-    exit('No direct script access allowed');
4
+	exit('No direct script access allowed');
5 5
 
6 6
 /*
7 7
   |--------------------------------------------------------------------------
@@ -374,52 +374,52 @@  discard block
 block discarded – undo
374 374
  */
375 375
 $config['proxy_ips'] = '';
376 376
 $config['Origination-rates-field'] = array('code' => 'pattern',
377
-    'destination' => 'comment',
378
-    'connect cost' => 'connectcost',
379
-    'included seconds' => 'includedseconds',
380
-    'per minute cost' => 'cost',
381
-    'initial increment' => 'init_inc',
382
-    'increment' => 'inc',
377
+	'destination' => 'comment',
378
+	'connect cost' => 'connectcost',
379
+	'included seconds' => 'includedseconds',
380
+	'per minute cost' => 'cost',
381
+	'initial increment' => 'init_inc',
382
+	'increment' => 'inc',
383 383
 );
384 384
 $config['Termination-rates-field'] = array('code' => 'pattern',
385
-    'destination' => 'comment',
386
-    'connect cost' => 'connectcost',
387
-    'included seconds' => 'includedseconds',
388
-    'per minute cost' => 'cost',
389
-    'initial increment' => 'init_inc',
390
-    'increment' => 'inc',
391
-    'precedence' => 'precedence',
392
-    'strip' => "strip",
393
-    'prepend' => 'prepend',
385
+	'destination' => 'comment',
386
+	'connect cost' => 'connectcost',
387
+	'included seconds' => 'includedseconds',
388
+	'per minute cost' => 'cost',
389
+	'initial increment' => 'init_inc',
390
+	'increment' => 'inc',
391
+	'precedence' => 'precedence',
392
+	'strip' => "strip",
393
+	'prepend' => 'prepend',
394 394
 );
395 395
 $config['DID-rates-field'] = array('DID' => 'number',
396
-    'Country' => 'country_id',
397
-    'Account' => 'accountid',
398
-    'Per Minute Cost(CURRENCY)' => 'cost',
399
-    "Initial Increment" => "init_inc",
400
-    'Increment' => 'inc',
401
-    'Setup Fee(CURRENCY)' => 'setup',
402
-    'Monthly Fee(CURRENCY)' => 'monthlycost',
403
-    'Call Type' => 'call_type',
404
-    'Destination' => 'extensions',
405
-    "Status" => 'status',
396
+	'Country' => 'country_id',
397
+	'Account' => 'accountid',
398
+	'Per Minute Cost(CURRENCY)' => 'cost',
399
+	"Initial Increment" => "init_inc",
400
+	'Increment' => 'inc',
401
+	'Setup Fee(CURRENCY)' => 'setup',
402
+	'Monthly Fee(CURRENCY)' => 'monthlycost',
403
+	'Call Type' => 'call_type',
404
+	'Destination' => 'extensions',
405
+	"Status" => 'status',
406 406
 );
407 407
 $config['invoices_path'] = FCPATH . "invoices/";
408 408
 $config['invoice_screen'] = FCPATH . APPPATH . "controllers/";
409 409
 $config['rates-file-path'] = ASSETSDIR . "Rates_File/uploaded_files/";
410 410
 $config['db_upload-file-path'] = "/tmp/";
411 411
 $config['Origin-rates-field'] = array('code' => 'pattern',
412
-    'prepend' => 'prepend',
413
-    'destination' => 'comment',
414
-    'connect cost' => 'connectcost',
415
-    'included seconds' => 'includedseconds',
416
-    'per minute cost' => 'cost',
417
-    'increment' => 'inc',
418
-    'precedence' => 'precedence',
419
-    'strip' => "strip",
412
+	'prepend' => 'prepend',
413
+	'destination' => 'comment',
414
+	'connect cost' => 'connectcost',
415
+	'included seconds' => 'includedseconds',
416
+	'per minute cost' => 'cost',
417
+	'increment' => 'inc',
418
+	'precedence' => 'precedence',
419
+	'strip' => "strip",
420 420
 );
421 421
 $config['package-code-field'] = array('code' => 'patterns',
422
-    'destination' => 'destination',
422
+	'destination' => 'destination',
423 423
 );
424 424
 $config['invoices_path'] = FCPATH . "invoices/";
425 425
 $config['invoice_template'] = APPPATH."views/";
Please login to merge, or discard this patch.