Some assorted fixes for html2pdf (converted line endings) and the patient report.
[openemr.git] / library / html2pdf / styleHTML.class.php
blob189d70a9812cf84477c5628dc4ce5ded6fca5abf
1 <?php
2 /**
3 * Logiciel : HTML2PDF - classe styleHTML
4 *
5 * Convertisseur HTML => PDF
6 * Distribué sous la licence LGPL.
8 * @author Laurent MINGUET <webmaster@html2pdf.fr>
9 * @version 3.31
12 class styleHTML
14 var $pdf = null; // référence au PDF parent
15 var $htmlColor = array(); // liste des couleurs HTML
16 var $onlyLeft = false; // indique si on est dans un sous HTML et qu'on bloque à gauche
17 var $defaultFont = null; // fonte par défaut si la fonte demandée n'existe pas
19 var $value = array(); // valeurs actuelles
20 var $css = array(); // tableau des CSS
21 var $css_keys = array(); // tableau des clefs CSS, pour l'ordre d'execution
22 var $table = array(); // tableau d'empilement pour historisation des niveaux
24 /**
25 * Constructeur
27 * @param &pdf référence à l'objet HTML2PDF parent
28 * @return null
30 function styleHTML(&$pdf)
32 $this->init(); // initialisation
33 $this->setPdfParent($pdf);
36 function setPdfParent(&$pdf)
38 $this->pdf = &$pdf;
41 function setOnlyLeft()
43 $this->value['text-align'] = 'left';
44 $this->onlyLeft = true;
47 function getOldValues()
49 return isset($this->table[count($this->table)-1]) ? $this->table[count($this->table)-1] : $this->value;
52 /**
53 * définit la fonte par défaut si aucun fonte n'est spécifiée, ou si la fonte demandée n'existe pas
55 * @param string nom de la fonte par defaut. si null : Arial pour fonte non spécifiée, et erreur pour fonte non existante
56 * @return string nom de l'ancienne fonte par defaut
58 function setDefaultFont($default = null)
60 $old = $this->defaultFont;
61 $this->defaultFont = $default;
62 if ($default) $this->value['font-family'] = $default;
63 return $old;
66 /**
67 * Initialisation du style
69 * @return null
71 function init()
73 global $webcolor;
74 $this->htmlColor = &$webcolor;
76 $this->table = array();
77 $this->value = array();
78 $this->initStyle();
80 // initialisation des styles sans héritages
81 $this->resetStyle();
84 function initStyle()
86 $this->value['id_balise'] = 'body'; // balise
87 $this->value['id_name'] = null; // name
88 $this->value['id_id'] = null; // id
89 $this->value['id_class'] = null; // class
90 $this->value['id_lst'] = array('*'); // lst de dependance
91 $this->value['mini-size'] = 1.; // rapport de taille spécifique aux sup, sub
92 $this->value['mini-decal'] = 0; // rapport de position spécifique aux sup, sub
93 $this->value['font-family'] = 'Arial';
94 $this->value['font-bold'] = false;
95 $this->value['font-italic'] = false;
96 $this->value['font-underline'] = false;
97 $this->value['font-overline'] = false;
98 $this->value['font-linethrough'] = false;
99 $this->value['text-transform'] = 'none';
100 $this->value['font-size'] = $this->ConvertToMM('10pt');
101 $this->value['text-indent'] = 0;
102 $this->value['text-align'] = 'left';
103 $this->value['vertical-align'] = 'middle';
104 $this->value['line-height'] = 'normal';
106 $this->value['position'] = null;
107 $this->value['x'] = null;
108 $this->value['y'] = null;
109 $this->value['width'] = 0;
110 $this->value['height'] = 0;
111 $this->value['top'] = null;
112 $this->value['right'] = null;
113 $this->value['bottom'] = null;
114 $this->value['left'] = null;
115 $this->value['float'] = null;
116 $this->value['display'] = null;
117 $this->value['rotate'] = null;
118 $this->value['overflow'] = 'visible';
120 $this->value['color'] = array(0, 0, 0);
121 $this->value['background'] = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
122 $this->value['border'] = array();
123 $this->value['padding'] = array();
124 $this->value['margin'] = array();
125 $this->value['margin-auto'] = false;
127 $this->value['list-style-type'] = '';
128 $this->value['list-style-image'] = '';
130 $this->value['xc'] = null;
131 $this->value['yc'] = null;
135 * Initialisation des styles sans héritages
137 * @param string balise HTML
138 * @return null
140 function resetStyle($balise = '')
142 $collapse = isset($this->value['border']['collapse']) ? $this->value['border']['collapse'] : false;
143 if (!in_array($balise, array('tr', 'td', 'th', 'thead', 'tbody', 'tfoot'))) $collapse = false;
145 $this->value['position'] = null;
146 $this->value['x'] = null;
147 $this->value['y'] = null;
148 $this->value['width'] = 0;
149 $this->value['height'] = 0;
150 $this->value['top'] = null;
151 $this->value['right'] = null;
152 $this->value['bottom'] = null;
153 $this->value['left'] = null;
154 $this->value['float'] = null;
155 $this->value['display'] = null;
156 $this->value['rotate'] = null;
157 $this->value['overflow'] = 'visible';
158 $this->value['background'] = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
159 $this->value['border'] = array(
160 't' => $this->readBorder('none'),
161 'r' => $this->readBorder('none'),
162 'b' => $this->readBorder('none'),
163 'l' => $this->readBorder('none'),
164 'radius' => array(
165 'tl' => array(0, 0),
166 'tr' => array(0, 0),
167 'br' => array(0, 0),
168 'bl' => array(0, 0)
170 'collapse' => $collapse,
173 if (!in_array($balise, array('h1', 'h2', 'h3', 'h4', 'h5', 'h6')))
174 $this->value['margin'] = array('t'=>0,'r'=>0,'b'=>0,'l'=>0);
176 if ($balise=='p')
178 $this->value['margin']['t'] = null;
179 $this->value['margin']['b'] = null;
181 $this->value['margin-auto'] = false;
183 if (in_array($balise, array('div', 'fieldset')))
184 $this->value['vertical-align'] = 'top';
186 if (in_array($balise, array('fieldset', 'legend')))
188 $radius = $this->ConvertToMM('5px');
189 $this->value['border'] = array(
190 't' => $this->readBorder('solid 1px #000000'),
191 'r' => $this->readBorder('solid 1px #000000'),
192 'b' => $this->readBorder('solid 1px #000000'),
193 'l' => $this->readBorder('solid 1px #000000'),
194 'radius' => array(),
195 'collapse' => false,
198 $this->value['border']['radius'] = array(
199 'tl' => array($radius, $radius),
200 'tr' => array($radius, $radius),
201 'br' => array($radius, $radius),
202 'bl' => array($radius, $radius));
205 if (in_array($balise, array('ul', 'li')))
207 $this->value['list-style-type'] = '';
208 $this->value['list-style-image'] = '';
211 if (!in_array($balise, array('tr', 'td')))
213 $this->value['padding'] = array(
214 't' => 0,
215 'r' => 0,
216 'b' => 0,
217 'l' => 0
220 else
222 $this->value['padding'] = array(
223 't' => $this->ConvertToMM('1px'),
224 'r' => $this->ConvertToMM('1px'),
225 'b' => $this->ConvertToMM('1px'),
226 'l' => $this->ConvertToMM('1px')
230 if ($balise=='hr')
232 $this->value['border'] = array(
233 't' => $this->readBorder('solid 1px #000000'),
234 'r' => $this->readBorder('solid 1px #000000'),
235 'b' => $this->readBorder('solid 1px #000000'),
236 'l' => $this->readBorder('solid 1px #000000'),
237 'radius' => array(
238 'tl' => array(0, 0),
239 'tr' => array(0, 0),
240 'br' => array(0, 0),
241 'bl' => array(0, 0)
243 'collapse' => false,
245 $this->ConvertBackground('#FFFFFF', $this->value['background']);
248 $this->value['xc'] = null;
249 $this->value['yc'] = null;
253 * Initialisation de la font PDF
255 * @return null
257 function FontSet()
259 $family = strtolower($this->value['font-family']);
261 $b = ($this->value['font-bold'] ? 'B' : '');
262 $i = ($this->value['font-italic'] ? 'I' : '');
263 $u = ($this->value['font-underline'] ? 'U' : '');
264 $d = ($this->value['font-linethrough'] ? 'D' : '');
265 $o = ($this->value['font-overline'] ? 'O' : '');
267 if ($this->defaultFont)
269 $style = $b.$i;
270 if($family=='arial')
271 $family='helvetica';
272 elseif($family=='symbol' || $family=='zapfdingbats')
273 $style='';
275 $fontkey = $family.$style;
276 if (!$this->pdf->isLoadedFont($fontkey))
277 $family = $this->defaultFont;
280 if($family=='arial')
281 $family='helvetica';
282 elseif($family=='symbol' || $family=='zapfdingbats')
283 $style='';
285 // taille en mm, à ramener en pt
286 $size = $this->value['font-size'];
287 $size = 72 * $size / 25.4;
289 $this->pdf->setOverline($o ? true : false);
290 $this->pdf->setLinethrough($d ? true : false);
292 // application de la fonte
293 $this->pdf->SetFont($family, $b.$i.$u, $this->value['mini-size']*$size);
294 $this->pdf->setMyTextColor($this->value['color']);
295 if ($this->value['background']['color'])
296 $this->pdf->setMyFillColor($this->value['background']['color']);
297 else
298 $this->pdf->setMyFillColor(1.);
302 * Monter d'un niveau dans l'historisation
304 * @return null
306 function save()
308 $this->table[count($this->table)] = $this->value;
312 * Descendre d'un niveau dans l'historisation
314 * @return null
316 function load()
318 if (count($this->table))
320 $this->value = $this->table[count($this->table)-1];
321 unset($this->table[count($this->table)-1]);
325 function restorePosition()
327 if ($this->value['y']==$this->pdf->getY()) $this->pdf->setY($this->value['yc'], false);
330 function setPosition()
332 $current_x = $this->pdf->getX();
333 $current_y = $this->pdf->getY();
334 $this->value['xc'] = $current_x;
335 $this->value['yc'] = $current_y;
337 if ($this->value['position']=='relative' || $this->value['position']=='absolute')
339 if ($this->value['right']!==null)
341 $x = $this->getLastWidth(true) - $this->value['right'] - $this->value['width'];
342 if ($this->value['margin']['r']) $x-= $this->value['margin']['r'];
344 else
346 $x = $this->value['left'];
347 if ($this->value['margin']['l']) $x+= $this->value['margin']['l'];
350 if ($this->value['bottom']!==null)
352 $y = $this->getLastHeight(true) - $this->value['bottom'] - $this->value['height'];
353 if ($this->value['margin']['b']) $y-= $this->value['margin']['b'];
355 else
357 $y = $this->value['top'];
358 if ($this->value['margin']['t']) $y+= $this->value['margin']['t'];
361 if ($this->value['position']=='relative')
363 $this->value['x'] = $current_x + $x;
364 $this->value['y'] = $current_y + $y;
366 else
368 $this->value['x'] = $this->getLastAbsoluteX()+$x;
369 $this->value['y'] = $this->getLastAbsoluteY()+$y;
372 else
374 $this->value['x'] = $current_x;
375 $this->value['y'] = $current_y;
376 if ($this->value['margin']['l']) $this->value['x']+= $this->value['margin']['l'];
377 if ($this->value['margin']['t']) $this->value['y']+= $this->value['margin']['t'];
380 $this->pdf->setXY($this->value['x'], $this->value['y']);
384 * Analyse un tableau de style provenant du parseurHTML
386 * @param string nom de la balise
387 * @param array tableau de style
388 * @return null
391 function getSvgStyle($balise, &$param)
393 // preparation
394 $balise = strtolower($balise);
395 $id = isset($param['id']) ? strtolower(trim($param['id'])) : null; if (!$id) $id = null;
396 $name = isset($param['name']) ? strtolower(trim($param['name'])) : null; if (!$name) $name = null;
398 // lecture de la propriete classe
399 $class = array();
400 $tmp = isset($param['class']) ? strtolower(trim($param['class'])) : '';
401 $tmp = explode(' ', $tmp);
402 foreach($tmp as $k => $v)
404 $v = trim($v);
405 if ($v) $class[] = $v;
408 // identification de la balise et des styles direct qui pourraient lui être appliqués
409 $this->value['id_balise'] = $balise;
410 $this->value['id_name'] = $name;
411 $this->value['id_id'] = $id;
412 $this->value['id_class'] = $class;
413 $this->value['id_lst'] = array();
414 $this->value['id_lst'][] = '*';
415 $this->value['id_lst'][] = $balise;
416 if (!isset($this->value['svg']))
418 $this->value['svg'] = array(
419 'stroke' => null,
420 'stroke-width' => $this->ConvertToMM('1pt'),
421 'fill' => null,
422 'fill-opacity' => null,
426 if (count($class))
428 foreach($class as $v)
430 $this->value['id_lst'][] = '*.'.$v;
431 $this->value['id_lst'][] = '.'.$v;
432 $this->value['id_lst'][] = $balise.'.'.$v;
435 if ($id)
437 $this->value['id_lst'][] = '*#'.$id;
438 $this->value['id_lst'][] = '#'.$id;
439 $this->value['id_lst'][] = $balise.'#'.$id;
442 // style CSS
443 $styles = $this->getFromCSS();
445 // on ajoute le style propre à la balise
446 $styles = array_merge($styles, $param['style']);
448 if (isset($styles['stroke'])) $this->value['svg']['stroke'] = $this->ConvertToColor($styles['stroke'], $res);
449 if (isset($styles['stroke-width'])) $this->value['svg']['stroke-width'] = $this->ConvertToMM($styles['stroke-width']);
450 if (isset($styles['fill'])) $this->value['svg']['fill'] = $this->ConvertToColor($styles['fill'], $res);
451 if (isset($styles['fill-opacity'])) $this->value['svg']['fill-opacity'] = 1.*$styles['fill-opacity'];
453 return $this->value['svg'];
457 * Analyse un tableau de style provenant du parseurHTML
459 * @param string nom de la balise
460 * @param array tableau de style
461 * @param array tableau initialisant des styles
462 * @return null
464 function analyse($balise, &$param, $heritage = null)
466 // preparation
467 $balise = strtolower($balise);
468 $id = isset($param['id']) ? strtolower(trim($param['id'])) : null; if (!$id) $id = null;
469 $name = isset($param['name']) ? strtolower(trim($param['name'])) : null; if (!$name) $name = null;
471 // lecture de la propriete classe
472 $class = array();
473 $tmp = isset($param['class']) ? strtolower(trim($param['class'])) : '';
474 $tmp = explode(' ', $tmp);
475 foreach($tmp as $k => $v)
477 $v = trim($v);
478 if ($v) $class[] = $v;
481 // identification de la balise et des styles direct qui pourraient lui être appliqués
482 $this->value['id_balise'] = $balise;
483 $this->value['id_name'] = $name;
484 $this->value['id_id'] = $id;
485 $this->value['id_class'] = $class;
486 $this->value['id_lst'] = array();
487 $this->value['id_lst'][] = '*';
488 $this->value['id_lst'][] = $balise;
489 if (count($class))
491 foreach($class as $v)
493 $this->value['id_lst'][] = '*.'.$v;
494 $this->value['id_lst'][] = '.'.$v;
495 $this->value['id_lst'][] = $balise.'.'.$v;
498 if ($id)
500 $this->value['id_lst'][] = '*#'.$id;
501 $this->value['id_lst'][] = '#'.$id;
502 $this->value['id_lst'][] = $balise.'#'.$id;
505 // style CSS
506 $styles = $this->getFromCSS();
508 // on ajoute le style propre à la balise
509 $styles = array_merge($styles, $param['style']);
510 if (isset($param['allwidth']) && !isset($styles['width'])) $styles['width'] = '100%';
512 // mise à zero des styles non hérités
513 $this->resetStyle($balise);
514 if ($heritage)
516 foreach($heritage as $he_nom => $he_val)
518 if (is_array($he_val))
520 foreach($he_val as $he2_nom => $he2_val)
521 $this->value[$he_nom][$he2_nom] = $he2_val;
523 else
524 $this->value[$he_nom] = $he_val;
528 // interpreration des nouvelles valeurs
529 $correct_width = false;
530 $no_width = true;
532 foreach($styles as $nom => $val)
534 switch($nom)
536 case 'font-family':
537 $val = explode(',', $val);
538 $val = trim($val[0]);
540 if ($val) $this->value['font-family'] = $val;
541 break;
543 case 'font-weight':
544 $this->value['font-bold'] = ($val=='bold');
545 break;
547 case 'font-style':
548 $this->value['font-italic'] = ($val=='italic');
549 break;
551 case 'text-decoration':
552 $val = explode(' ', $val);
553 $this->value['font-underline'] = (in_array('underline', $val));
554 $this->value['font-overline'] = (in_array('overline', $val));
555 $this->value['font-linethrough'] = (in_array('line-through', $val));
556 break;
558 case 'text-indent':
559 $this->value['text-indent'] = $this->ConvertToMM($val);
560 break;
562 case 'text-transform':
563 if (!in_array($val, array('none', 'capitalize', 'uppercase', 'lowercase'))) $val = 'none';
564 $this->value['text-transform'] = $val;
565 break;
567 case 'font-size':
568 $val = $this->ConvertToMM($val, $this->value['font-size']);
569 if ($val) $this->value['font-size'] = $val;
570 break;
572 case 'color':
573 $res = null;
574 $this->value['color'] = $this->ConvertToColor($val, $res);
576 if ($balise=='hr')
578 $this->value['border']['l']['color'] = $this->value['color'];
579 $this->value['border']['t']['color'] = $this->value['color'];
580 $this->value['border']['r']['color'] = $this->value['color'];
581 $this->value['border']['b']['color'] = $this->value['color'];
583 break;
585 case 'text-align':
586 $val = strtolower($val);
587 if (!in_array($val, array('left', 'right', 'center', 'justify', 'li_right'))) $val = 'left';
588 $this->value['text-align'] = $val;
589 break;
591 case 'vertical-align':
592 $this->value['vertical-align'] = $val;
593 break;
595 case 'width':
596 $this->value['width'] = $this->ConvertToMM($val, $this->getLastWidth());
597 if ($this->value['width'] && substr($val, -1)=='%') $correct_width=true;
598 $no_width = false;
599 break;
601 case 'height':
602 $this->value['height'] = $this->ConvertToMM($val, $this->getLastHeight());
603 break;
605 case 'line-height':
606 if (preg_match('/^[0-9\.]+$/isU', $val)) $val = floor($val*100).'%';
607 $this->value['line-height'] = $val;
608 break;
610 case 'rotate':
611 if (!in_array($val, array(0, -90, 90, 180, 270, -180, -270))) $val = null;
612 if ($val<0) $val+= 360;
613 $this->value['rotate'] = $val;
614 break;
616 case 'overflow':
617 if (!in_array($val, array('visible', 'hidden'))) $val = 'visible';
618 $this->value['overflow'] = $val;
619 break;
621 case 'padding':
622 $val = explode(' ', $val);
623 foreach($val as $k => $v)
625 $v = trim($v);
626 if ($v!='') $val[$k] = $v;
627 else unset($val[$k]);
629 $val = array_values($val);
630 $this->duplicateBorder($val);
632 $this->value['padding']['t'] = $this->ConvertToMM($val[0], 0);
633 $this->value['padding']['r'] = $this->ConvertToMM($val[1], 0);
634 $this->value['padding']['b'] = $this->ConvertToMM($val[2], 0);
635 $this->value['padding']['l'] = $this->ConvertToMM($val[3], 0);
636 break;
638 case 'padding-top':
639 $this->value['padding']['t'] = $this->ConvertToMM($val, 0);
640 break;
642 case 'padding-right':
643 $this->value['padding']['r'] = $this->ConvertToMM($val, 0);
644 break;
646 case 'padding-bottom':
647 $this->value['padding']['b'] = $this->ConvertToMM($val, 0);
648 break;
650 case 'padding-left':
651 $this->value['padding']['l'] = $this->ConvertToMM($val, 0);
652 break;
654 case 'margin':
655 if ($val=='auto')
657 $this->value['margin-auto'] = true;
658 break;
660 $val = explode(' ', $val);
661 foreach($val as $k => $v)
663 $v = trim($v);
664 if ($v!='') $val[$k] = $v;
665 else unset($val[$k]);
667 $val = array_values($val);
668 $this->duplicateBorder($val);
670 $this->value['margin']['t'] = $this->ConvertToMM($val[0], 0);
671 $this->value['margin']['r'] = $this->ConvertToMM($val[1], 0);
672 $this->value['margin']['b'] = $this->ConvertToMM($val[2], 0);
673 $this->value['margin']['l'] = $this->ConvertToMM($val[3], 0);
674 break;
676 case 'margin-top':
677 $this->value['margin']['t'] = $this->ConvertToMM($val, 0);
678 break;
680 case 'margin-right':
681 $this->value['margin']['r'] = $this->ConvertToMM($val, 0);
682 break;
684 case 'margin-bottom':
685 $this->value['margin']['b'] = $this->ConvertToMM($val, 0);
686 break;
688 case 'margin-left':
689 $this->value['margin']['l'] = $this->ConvertToMM($val, 0);
690 break;
692 case 'border':
693 $val = $this->readBorder($val);
694 $this->value['border']['t'] = $val;
695 $this->value['border']['r'] = $val;
696 $this->value['border']['b'] = $val;
697 $this->value['border']['l'] = $val;
698 break;
700 case 'border-style':
701 $val = explode(' ', $val);
702 foreach($val as $val_k => $val_v)
703 if (!in_array($val_v, array('solid', 'dotted', 'dashed')))
704 $val[$val_k] = null;
705 $this->duplicateBorder($val);
707 if ($val[0]) $this->value['border']['t']['type'] = $val[0];
708 if ($val[1]) $this->value['border']['r']['type'] = $val[1];
709 if ($val[2]) $this->value['border']['b']['type'] = $val[2];
710 if ($val[3]) $this->value['border']['l']['type'] = $val[3];
711 break;
713 case 'border-top-style':
714 if (in_array($val, array('solid', 'dotted', 'dashed')))
715 $this->value['border']['t']['type'] = $val;
716 break;
718 case 'border-right-style':
719 if (in_array($val, array('solid', 'dotted', 'dashed')))
720 $this->value['border']['r']['type'] = $val;
721 break;
723 case 'border-bottom-style':
724 if (in_array($val, array('solid', 'dotted', 'dashed')))
725 $this->value['border']['b']['type'] = $val;
726 break;
728 case 'border-left-style':
729 if (in_array($val, array('solid', 'dotted', 'dashed')))
730 $this->value['border']['l']['type'] = $val;
731 break;
733 case 'border-color':
734 $res = false;
735 $val = preg_replace('/,[\s]+/', ',', $val);
736 $val = explode(' ', $val);
738 foreach($val as $val_k => $val_v)
740 $val[$val_k] = $this->ConvertToColor($val_v, $res);
741 if (!$res) $val[$val_k] = null;
743 $this->duplicateBorder($val);
745 if (is_array($val[0])) $this->value['border']['t']['color'] = $val[0];
746 if (is_array($val[1])) $this->value['border']['r']['color'] = $val[1];
747 if (is_array($val[2])) $this->value['border']['b']['color'] = $val[2];
748 if (is_array($val[3])) $this->value['border']['l']['color'] = $val[3];
750 break;
752 case 'border-top-color':
753 $res = false;
754 $val = $this->ConvertToColor($val, $res);
755 if ($res) $this->value['border']['t']['color'] = $val;
756 break;
758 case 'border-right-color':
759 $res = false;
760 $val = $this->ConvertToColor($val, $res);
761 if ($res) $this->value['border']['r']['color'] = $val;
762 break;
764 case 'border-bottom-color':
765 $res = false;
766 $val = $this->ConvertToColor($val, $res);
767 if ($res) $this->value['border']['b']['color'] = $val;
768 break;
770 case 'border-left-color':
771 $res = false;
772 $val = $this->ConvertToColor($val, $res);
773 if ($res) $this->value['border']['l']['color'] = $val;
774 break;
776 case 'border-width':
777 $val = explode(' ', $val);
778 foreach($val as $val_k => $val_v)
780 $val[$val_k] = $this->ConvertToMM($val_v, 0);
782 $this->duplicateBorder($val);
784 if ($val[0]) $this->value['border']['t']['width'] = $val[0];
785 if ($val[1]) $this->value['border']['r']['width'] = $val[1];
786 if ($val[2]) $this->value['border']['b']['width'] = $val[2];
787 if ($val[3]) $this->value['border']['l']['width'] = $val[3];
788 break;
790 case 'border-top-width':
791 $val = $this->ConvertToMM($val, 0);
792 if ($val) $this->value['border']['t']['width'] = $val;
793 break;
795 case 'border-right-width':
796 $val = $this->ConvertToMM($val, 0);
797 if ($val) $this->value['border']['r']['width'] = $val;
798 break;
800 case 'border-bottom-width':
801 $val = $this->ConvertToMM($val, 0);
802 if ($val) $this->value['border']['b']['width'] = $val;
803 break;
805 case 'border-left-width':
806 $val = $this->ConvertToMM($val, 0);
807 if ($val) $this->value['border']['l']['width'] = $val;
808 break;
810 case 'border-collapse':
811 if ($balise=='table') $this->value['border']['collapse'] = ($val=='collapse');
812 break;
814 case 'border-radius':
815 $val = explode('/', $val); if (count($val)>2) break;
817 $val_h = $this->ConvertToRadius(trim($val[0]));
818 if (count($val_h)<1 || count($val_h)>4) break;
819 if (!isset($val_h[1])) $val_h[1] = $val_h[0];
820 if (!isset($val_h[2])) $val_h = array($val_h[0], $val_h[0], $val_h[1], $val_h[1]);
821 if (!isset($val_h[3])) $val_h[3] = $val_h[1];
823 if (isset($val[1]))
825 $val_v = $this->ConvertToRadius(trim($val[1]));
826 if (count($val_v)<1 || count($val_v)>4) break;
827 if (!isset($val_v[1])) $val_v[1] = $val_v[0];
828 if (!isset($val_v[2])) $val_v = array($val_v[0], $val_v[0], $val_v[1], $val_v[1]);
829 if (!isset($val_v[3])) $val_v[3] = $val_v[1];
831 else
832 $val_v = $val_h;
834 $this->value['border']['radius'] = array(
835 'tl' => array($val_h[0], $val_v[0]),
836 'tr' => array($val_h[1], $val_v[1]),
837 'br' => array($val_h[2], $val_v[2]),
838 'bl' => array($val_h[3], $val_v[3])
840 break;
842 case 'border-top-left-radius':
843 $val = $this->ConvertToRadius($val);
844 if (count($val)<1 || count($val)>2) break;
845 $this->value['border']['radius']['tl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
846 break;
848 case 'border-top-right-radius':
849 $val = $this->ConvertToRadius($val);
850 if (count($val)<1 || count($val)>2) break;
851 $this->value['border']['radius']['tr'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
852 break;
854 case 'border-bottom-right-radius':
855 $val = $this->ConvertToRadius($val);
856 if (count($val)<1 || count($val)>2) break;
857 $this->value['border']['radius']['br'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
858 break;
860 case 'border-bottom-left-radius':
861 $val = $this->ConvertToRadius($val);
862 if (count($val)<1 || count($val)>2) break;
863 $this->value['border']['radius']['bl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
864 break;
866 case 'border-top':
867 $this->value['border']['t'] = $this->readBorder($val);
868 break;
870 case 'border-right':
871 $this->value['border']['r'] = $this->readBorder($val);
872 break;
874 case 'border-bottom':
875 $this->value['border']['b'] = $this->readBorder($val);
876 break;
878 case 'border-left':
879 $this->value['border']['l'] = $this->readBorder($val);
880 break;
882 case 'background-color':
883 $this->value['background']['color'] = $this->ConvertBackgroundColor($val);
884 break;
886 case 'background-image':
887 $this->value['background']['image'] = $this->ConvertBackgroundImage($val);
888 break;
890 case 'background-position':
891 $res = null;
892 $this->value['background']['position'] = $this->ConvertBackgroundPosition($val, $res);
893 break;
895 case 'background-repeat':
896 $this->value['background']['repeat'] = $this->ConvertBackgroundRepeat($val);
897 break;
899 case 'background':
900 $this->ConvertBackground($val, $this->value['background']);
901 break;
903 case 'position':
904 if ($val=='absolute') $this->value['position'] = 'absolute';
905 else if ($val=='relative') $this->value['position'] = 'relative';
906 else $this->value['position'] = null;
907 break;
909 case 'float':
910 if ($val=='left') $this->value['float'] = 'left';
911 else if ($val=='right') $this->value['float'] = 'right';
912 else $this->value['float'] = null;
913 break;
915 case 'display':
916 if ($val=='inline') $this->value['display'] = 'inline';
917 else if ($val=='block') $this->value['display'] = 'block';
918 else if ($val=='none') $this->value['display'] = 'none';
919 else $this->value['display'] = null;
920 break;
922 case 'top':
923 case 'bottom':
924 case 'left':
925 case 'right':
926 $this->value[$nom] = $val;
927 break;
929 case 'list-style':
930 case 'list-style-type':
931 case 'list-style-image':
932 if ($nom=='list-style') $nom = 'list-style-type';
933 $this->value[$nom] = $val;
934 break;
936 default:
937 break;
941 $return = true;
943 if ($this->value['margin']['t']===null) $this->value['margin']['t'] = $this->value['font-size'];
944 if ($this->value['margin']['b']===null) $this->value['margin']['b'] = $this->value['font-size'];
946 if ($this->onlyLeft) $this->value['text-align'] = 'left';
948 // correction de la largeur pour correspondre au modèle de boite quick
949 if ($no_width && in_array($balise, array('div', 'fieldset')) && $this->value['position']!='absolute')
951 $this->value['width'] = $this->getLastWidth();
952 $this->value['width']-= $this->value['margin']['l'] + $this->value['margin']['r'];
954 else
956 if ($correct_width)
958 if (!in_array($balise, array('table', 'div', 'fieldset', 'hr')))
960 $this->value['width']-= $this->value['padding']['l'] + $this->value['padding']['r'];
961 $this->value['width']-= $this->value['border']['l']['width'] + $this->value['border']['r']['width'];
963 if (in_array($balise, array('th', 'td')))
965 $this->value['width']-= $this->ConvertToMM(isset($param['cellspacing']) ? $param['cellspacing'] : '2px');
966 $return = false;
968 if ($this->value['width']<0) $this->value['width']=0;
970 else
972 if ($this->value['width'])
974 if ($this->value['border']['l']['width']) $this->value['width'] += $this->value['border']['l']['width'];
975 if ($this->value['border']['r']['width']) $this->value['width'] += $this->value['border']['r']['width'];
976 if ($this->value['padding']['l']) $this->value['width'] += $this->value['padding']['l'];
977 if ($this->value['padding']['r']) $this->value['width'] += $this->value['padding']['r'];
981 if ($this->value['height'])
983 if ($this->value['border']['b']['width']) { $this->value['height'] += $this->value['border']['b']['width']; }
984 if ($this->value['border']['t']['width']) { $this->value['height'] += $this->value['border']['t']['width']; }
985 if ($this->value['padding']['b']) $this->value['height'] += $this->value['padding']['b'];
986 if ($this->value['padding']['t']) $this->value['height'] += $this->value['padding']['t'];
989 if ($this->value['top']!=null) $this->value['top'] = $this->ConvertToMM($this->value['top'], $this->getLastHeight(true));
990 if ($this->value['bottom']!=null) $this->value['bottom'] = $this->ConvertToMM($this->value['bottom'], $this->getLastHeight(true));
991 if ($this->value['left']!=null) $this->value['left'] = $this->ConvertToMM($this->value['left'], $this->getLastWidth(true));
992 if ($this->value['right']!=null) $this->value['right'] = $this->ConvertToMM($this->value['right'], $this->getLastWidth(true));
994 if ($this->value['top'] && $this->value['bottom'] && $this->value['height']) $this->value['bottom'] = null;
995 if ($this->value['left'] && $this->value['right'] && $this->value['width']) $this->value['right'] = null;
997 return $return;
1001 * Récupération de la hauteur de ligne courante
1003 * @return float hauteur en mm
1005 function getLineHeight()
1007 $val = $this->value['line-height'];
1008 if ($val=='normal') $val = '108%';
1009 return $this->ConvertToMM($val, $this->value['font-size']);
1013 * Récupération de la largeur de l'objet parent
1015 * @return float largeur
1017 function getLastWidth($mode = false)
1019 for($k=count($this->table)-1; $k>=0; $k--)
1021 if ($this->table[$k]['width'])
1023 $w = $this->table[$k]['width'];
1024 if ($mode)
1026 $w+= $this->table[$k]['border']['l']['width'] + $this->table[$k]['padding']['l'] + 0.02;
1027 $w+= $this->table[$k]['border']['r']['width'] + $this->table[$k]['padding']['r'] + 0.02;
1029 return $w;
1032 return $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
1036 * Récupération de la hauteur de l'objet parent
1038 * @return float hauteur
1040 function getLastHeight($mode = false)
1042 for($k=count($this->table)-1; $k>=0; $k--)
1044 if ($this->table[$k]['height'])
1046 $h = $this->table[$k]['height'];
1047 if ($mode)
1049 $h+= $this->table[$k]['border']['t']['width'] + $this->table[$k]['padding']['t'] + 0.02;
1050 $h+= $this->table[$k]['border']['b']['width'] + $this->table[$k]['padding']['b'] + 0.02;
1052 return $h;
1055 return $this->pdf->getH() - $this->pdf->gettMargin() - $this->pdf->getbMargin();
1058 function getFloat()
1060 if ($this->value['float']=='left') return 'left';
1061 if ($this->value['float']=='right') return 'right';
1062 return null;
1065 function getLastValue($key)
1067 $nb = count($this->table);
1068 if ($nb>0)
1069 return $this->table[$nb-1][$key];
1070 return null;
1073 function getLastAbsoluteX()
1075 for($k=count($this->table)-1; $k>=0; $k--)
1077 if ($this->table[$k]['x'] && $this->table[$k]['position']) return $this->table[$k]['x'];
1079 return $this->pdf->getlMargin();
1082 function getLastAbsoluteY()
1084 for($k=count($this->table)-1; $k>=0; $k--)
1086 if ($this->table[$k]['y'] && $this->table[$k]['position']) return $this->table[$k]['y'];
1088 return $this->pdf->gettMargin();
1092 * Récupération des propriétés CSS de la balise en cours
1094 * @return array() tableau des propriétés CSS
1096 function getFromCSS()
1098 $styles = array(); // style à appliquer
1099 $getit = array(); // styles à récuperer
1101 // identification des styles direct, et ceux des parents
1102 $lst = array();
1103 $lst[] = $this->value['id_lst'];
1104 for($i=count($this->table)-1; $i>=0; $i--) $lst[] = $this->table[$i]['id_lst'];
1106 // identification des styles à récuperer
1107 foreach($this->css_keys as $key => $num)
1108 if ($this->getReccursiveStyle($key, $lst))
1109 $getit[$key] = $num;
1111 // si des styles sont à recuperer
1112 if (count($getit))
1114 // on les récupère, mais dans l'odre de définition, afin de garder les priorités
1115 asort($getit);
1116 foreach($getit as $key => $val) $styles = array_merge($styles, $this->css[$key]);
1119 return $styles;
1123 * Identification des styles à récuperer, en fonction de la balise et de ses parents
1125 * @param string clef CSS à analyser
1126 * @param array() tableau des styles direct, et ceux des parents
1127 * @param string prochaine etape
1128 * @return boolean clef autorisée ou non
1130 function getReccursiveStyle($key, $lst, $next = null)
1132 // si propchaine etape, on construit les valeurs
1133 if ($next!==null)
1135 if ($next) $key = trim(substr($key, 0, -strlen($next))); // on elève cette etape
1136 unset($lst[0]);
1137 if (!count($lst)) return false; // pas d'etape possible
1138 $lst = array_values($lst);
1141 // pour chaque style direct possible de l'etape en cours
1142 foreach($lst[0] as $nom)
1144 if ($key==$nom) return true; // si la clef conrrespond => ok
1145 if (substr($key, -strlen(' '.$nom))==' '.$nom && $this->getReccursiveStyle($key, $lst, $nom)) return true; // si la clef est la fin, on analyse ce qui précède
1148 // si on est pas à la premiere etape, on doit analyse toutes les sous etapes
1149 if ($next!==null && $this->getReccursiveStyle($key, $lst, '')) return true;
1151 // aucun style trouvé
1152 return false;
1156 * Analyse d'une propriété Border
1158 * @param string propriété border
1159 * @return array() propriété décodée
1161 function readBorder($val)
1163 $none = array('type' => 'none', 'width' => 0, 'color' => array(0, 0, 0));
1165 // valeurs par défault
1166 $type = 'solid';
1167 $width = $this->ConvertToMM('1pt');
1168 $color = array(0, 0, 0);
1170 // nettoyage des valeurs
1171 $val = explode(' ', $val);
1172 foreach($val as $k => $v)
1174 $v = trim($v);
1175 if ($v) $val[$k] = $v;
1176 else unset($val[$k]);
1178 $val = array_values($val);
1179 // identification des valeurs
1180 $res = null;
1181 foreach($val as $key)
1183 if ($key=='none' || $key=='hidden') return $none;
1185 if ($this->ConvertToMM($key)!==null)
1186 $width = $this->ConvertToMM($key);
1187 else if (in_array($key, array('solid', 'dotted', 'dashed', 'double')))
1188 $type = $key;
1189 else
1191 $tmp = $this->ConvertToColor($key, $res);
1192 if ($res) $color = $tmp;
1195 if (!$width) return $none;
1196 return array('type' => $type, 'width' => $width, 'color' => $color);
1199 function duplicateBorder(&$val)
1201 if (count($val)==1)
1203 $val[1] = $val[0];
1204 $val[2] = $val[0];
1205 $val[3] = $val[0];
1207 else if (count($val)==2)
1209 $val[2] = $val[0];
1210 $val[3] = $val[1];
1212 else if (count($val)==3)
1214 $val[3] = $val[1];
1218 function ConvertBackground($stl, &$res)
1220 // Image
1221 $text = '/url\(([^)]*)\)/isU';
1222 if (preg_match($text, $stl, $match))
1224 $res['image'] = $this->ConvertBackgroundImage($match[0]);
1225 $stl = preg_replace($text, '', $stl);
1226 $stl = preg_replace('/[\s]+/', ' ', $stl);
1229 // protection des espaces
1230 $stl = preg_replace('/,[\s]+/', ',', $stl);
1231 $lst = explode(' ', $stl);
1233 $pos = '';
1234 foreach($lst as $val)
1236 $ok = false;
1237 $color = $this->ConvertToColor($val, $ok);
1239 if ($ok)
1241 $res['color'] = $color;
1243 else if ($val=='transparent')
1245 $res['color'] = null;
1247 else
1249 $repeat = $this->ConvertBackgroundRepeat($val);
1250 if ($repeat)
1252 $res['repeat'] = $repeat;
1254 else
1256 $pos.= ($pos ? ' ' : '').$val;
1260 if ($pos)
1262 $pos = $this->ConvertBackgroundPosition($pos, $ok);
1263 if ($ok) $res['position'] = $pos;
1267 function ConvertBackgroundColor($val)
1269 $res = null;
1270 if ($val=='transparent') return null;
1271 else return $this->ConvertToColor($val, $res);
1274 function ConvertBackgroundImage($val)
1276 if ($val=='none')
1277 return null;
1278 else if (preg_match('/^url\(([^)]*)\)$/isU', $val, $match))
1279 return $match[1];
1280 else
1281 return null;
1284 function ConvertBackgroundPosition($val, &$res)
1286 $val = explode(' ', $val);
1287 if (count($val)<2)
1289 if (!$val[0]) return null;
1290 $val[1] = 'center';
1292 if (count($val)>2) return null;
1294 $x = 0;
1295 $y = 0;
1296 $res = true;
1298 if ($val[0]=='left') $x = '0%';
1299 else if ($val[0]=='center') $x = '50%';
1300 else if ($val[0]=='right') $x = '100%';
1301 else if ($val[0]=='top') $y = '0%';
1302 else if ($val[0]=='bottom') $y = '100%';
1303 else if (preg_match('/^[-]?[0-9\.]+%$/isU', $val[0])) $x = $val[0];
1304 else if ($this->ConvertToMM($val[0])) $x = $this->ConvertToMM($val[0]);
1305 else $res = false;
1307 if ($val[1]=='left') $x = '0%';
1308 else if ($val[1]=='right') $x = '100%';
1309 else if ($val[1]=='top') $y = '0%';
1310 else if ($val[1]=='center') $y = '50%';
1311 else if ($val[1]=='bottom') $y = '100%';
1312 else if (preg_match('/^[-]?[0-9\.]+%$/isU', $val[1])) $y = $val[1];
1313 else if ($this->ConvertToMM($val[1])) $y = $this->ConvertToMM($val[1]);
1314 else $res = false;
1316 $val[0] = $x;
1317 $val[1] = $y;
1319 return $val;
1322 function ConvertBackgroundRepeat($val)
1324 switch($val)
1326 case 'repeat':
1327 return array(true, true);
1328 case 'repeat-x':
1329 return array(true, false);
1330 case 'repeat-y':
1331 return array(false, true);
1332 case 'no-repeat':
1333 return array(false, false);
1335 return null;
1338 * Convertir une longueur en mm
1340 * @param string longueur, avec unité, à convertir
1341 * @param float longueur du parent
1342 * @return float longueur exprimée en mm
1344 function ConvertToMM($val, $old=0.)
1346 $val = trim($val);
1347 if (preg_match('/^[0-9\.\-]+$/isU', $val)) $val.= 'px';
1348 if (preg_match('/^[0-9\.\-]+px$/isU', $val)) $val = 25.4/96. * str_replace('px', '', $val);
1349 else if (preg_match('/^[0-9\.\-]+pt$/isU', $val)) $val = 25.4/72. * str_replace('pt', '', $val);
1350 else if (preg_match('/^[0-9\.\-]+in$/isU', $val)) $val = 25.4 * str_replace('in', '', $val);
1351 else if (preg_match('/^[0-9\.\-]+mm$/isU', $val)) $val = 1.*str_replace('mm', '', $val);
1352 else if (preg_match('/^[0-9\.\-]+%$/isU', $val)) $val = 1.*$old*str_replace('%', '', $val)/100.;
1353 else $val = null;
1355 return $val;
1358 function ConvertToRadius($val)
1360 $val = explode(' ', $val);
1361 foreach($val as $k => $v)
1363 $v = trim($v);
1364 if ($v)
1366 $v = $this->ConvertToMM($v, 0);
1367 if ($v!==null)
1368 $val[$k] = $v;
1369 else
1370 unset($val[$k]);
1372 else unset($val[$k]);
1374 return array_values($val);
1378 * Décomposition d'un code couleur HTML
1380 * @param string couleur au format CSS
1381 * @return array(r, v, b) couleur exprimé par ses comporantes R, V, B, de 0 à 255.
1383 function ConvertToColor($val, &$res)
1385 $val = trim($val);
1386 $res = true;
1388 if (strtolower($val)=='transparent') return array(null, null, null);
1389 if (isset($this->htmlColor[strtolower($val)]))
1391 $val = $this->htmlColor[strtolower($val)];
1392 $r = floatVal(hexdec(substr($val, 0, 2)));
1393 $v = floatVal(hexdec(substr($val, 2, 2)));
1394 $b = floatVal(hexdec(substr($val, 4, 2)));
1395 $col = array($r/255., $v/255., $b/255.);
1397 elseif (preg_match('/^#[0-9A-Fa-f]{6}$/isU', $val))
1399 $r = floatVal(hexdec(substr($val, 1, 2)));
1400 $v = floatVal(hexdec(substr($val, 3, 2)));
1401 $b = floatVal(hexdec(substr($val, 5, 2)));
1402 $col = array($r/255., $v/255., $b/255.);
1404 elseif (preg_match('/^#[0-9A-F]{3}$/isU', $val))
1406 $r = floatVal(hexdec(substr($val, 1, 1).substr($val, 1, 1)));
1407 $v = floatVal(hexdec(substr($val, 2, 1).substr($val, 2, 1)));
1408 $b = floatVal(hexdec(substr($val, 3, 1).substr($val, 3, 1)));
1409 $col = array($r/255., $v/255., $b/255.);
1411 elseif (preg_match('/rgb\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $val, $match))
1413 $r = $this->ConvertSubColor($match[1]);
1414 $v = $this->ConvertSubColor($match[2]);
1415 $b = $this->ConvertSubColor($match[3]);
1416 $col = array($r, $v, $b);
1418 elseif (preg_match('/cmyk\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $val, $match))
1420 $c = $this->ConvertSubColor($match[1]);
1421 $m = $this->ConvertSubColor($match[2]);
1422 $y = $this->ConvertSubColor($match[3]);
1423 $k = $this->ConvertSubColor($match[4]);
1424 $col = array($c, $m, $y, $k);
1426 else
1428 $col = array(0., 0., 0.);
1429 $res = false;
1432 return $col;
1435 function ConvertSubColor($c)
1437 if (substr($c, -1)=='%') $c = floatVal(substr($c, 0, -1))/100.;
1438 else
1440 $c = floatVal($c);
1441 if ($c>1) $c = $c/255.;
1443 return $c;
1447 * Analyser une feuille de style
1449 * @param string code CSS
1450 * @return null
1452 function analyseStyle(&$code)
1454 // on remplace tous les espaces, tab, \r, \n, par des espaces uniques
1455 $code = preg_replace('/[\s]+/', ' ', $code);
1457 // on enlève les commentaires
1458 $code = preg_replace('/\/\*.*?\*\//s', '', $code);
1460 // on analyse chaque style
1461 preg_match_all('/([^{}]+){([^}]*)}/isU', $code, $match);
1462 for($k=0; $k<count($match[0]); $k++)
1464 // noms
1465 $noms = strtolower(trim($match[1][$k]));
1467 // style, séparé par des; => on remplie le tableau correspondant
1468 $styles = trim($match[2][$k]);
1469 $styles = explode(';', $styles);
1470 $stl = array();
1471 foreach($styles as $style)
1473 $tmp = explode(':', $style);
1474 if (count($tmp)>1)
1476 $cod = $tmp[0]; unset($tmp[0]); $tmp = implode(':', $tmp);
1477 $stl[trim(strtolower($cod))] = trim($tmp);
1481 // décomposition des noms par les ,
1482 $noms = explode(',', $noms);
1483 foreach($noms as $nom)
1485 $nom = trim($nom);
1486 // Si il a une fonction spécifique, comme :hover => on zap
1487 if (strpos($nom, ':')!==false) continue;
1488 if (!isset($this->css[$nom]))
1489 $this->css[$nom] = $stl;
1490 else
1491 $this->css[$nom] = array_merge($this->css[$nom], $stl);
1496 $this->css_keys = array_flip(array_keys($this->css));
1500 * Extraction des feuille de style du code HTML
1502 * @param string code HTML
1503 * @return null
1505 function readStyle(&$html)
1507 $style = ' ';
1509 // extraction des balises link, et suppression de celles-ci dans le code HTML
1510 preg_match_all('/<link([^>]*)>/isU', $html, $match);
1511 $html = preg_replace('/<link[^>]*>/isU', '', $html);
1512 $html = preg_replace('/<\/link[^>]*>/isU', '', $html);
1514 // analyse de chaque balise
1515 foreach($match[1] as $code)
1517 $tmp = array();
1518 // lecture des paramétres du type nom=valeur
1519 $prop = '([a-zA-Z0-9_]+)=([^"\'\s>]+)';
1520 preg_match_all('/'.$prop.'/is', $code, $match);
1521 for($k=0; $k<count($match[0]); $k++)
1522 $tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1524 // lecture des paramétres du type nom="valeur"
1525 $prop = '([a-zA-Z0-9_]+)=["]([^"]*)["]';
1526 preg_match_all('/'.$prop.'/is', $code, $match);
1527 for($k=0; $k<count($match[0]); $k++)
1528 $tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1530 // lecture des paramétres du type nom='valeur'
1531 $prop = "([a-zA-Z0-9_]+)=[']([^']*)[']";
1532 preg_match_all('/'.$prop.'/is', $code, $match);
1533 for($k=0; $k<count($match[0]); $k++)
1534 $tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1536 // si de type text/css => on garde
1537 if (isset($tmp['type']) && strtolower($tmp['type'])=='text/css' && isset($tmp['href']))
1539 $content = @file_get_contents($tmp['href']);
1540 $url = $tmp['href'];
1541 if (strpos($url, 'http://')!==false)
1543 $url = str_replace('http://', '', $url);
1544 $url = explode('/', $url);
1545 $url_main = 'http://'.$url[0].'/';
1546 $url_self = $url; unset($url_self[count($url_self)-1]); $url_self = 'http://'.implode('/', $url_self).'/';
1548 $content = preg_replace('/url\(([^\\\\][^)]*)\)/isU', 'url('.$url_self.'$1)', $content);
1549 $content = preg_replace('/url\((\\\\[^)]*)\)/isU', 'url('.$url_main.'$1)', $content);
1551 else
1553 // @todo
1554 // $content = preg_replace('/url\(([^)]*)\)/isU', 'url('.dirname($url).'/$1)', $content);
1556 $style.= $content."\n";
1561 // extraction des balises style, et suppression de celles-ci dans le code HTML
1562 preg_match_all('/<style[^>]*>(.*)<\/style[^>]*>/isU', $html, $match);
1563 $html = preg_replace('/<style[^>]*>(.*)<\/style[^>]*>/isU', '', $html);
1565 // analyse de chaque balise
1566 foreach($match[1] as $code)
1568 $code = str_replace('<!--', '', $code);
1569 $code = str_replace('-->', '', $code);
1570 $style.= $code."\n";
1573 $this->analyseStyle($style);