<?php
/**
 * Logiciel : HTML2PDF - classe styleHTML
 * 
 * Convertisseur HTML => PDF
 * Distribu� sous la licence LGPL. 
 *
 * @author		Laurent MINGUET <webmaster@html2pdf.fr>
 * @version		4.01
 */

class styleHTML
{
	protected	$pdf			= null;			// r�f�rence au PDF parent
	protected	$htmlColor		= array();		// liste des couleurs HTML
	protected	$onlyLeft		= false;		// indique si on est dans un sous HTML et qu'on bloque � gauche
	protected	$defaultFont	= null;			// fonte par d�faut si la fonte demand�e n'existe pas
	
	public		$value			= array();		// valeurs actuelles
	public		$css			= array();		// tableau des CSS
	public		$css_keys		= array();		// tableau des clefs CSS, pour l'ordre d'execution
	public		$table			= array();		// tableau d'empilement pour historisation des niveaux
	
	/**
	 * Constructeur
	 *
	 * @param	&pdf		r�f�rence � l'objet HTML2PDF parent
	 * @return	null
	 */
	public function __construct(&$pdf)
	{
		$this->init();		// initialisation
		$this->setPdfParent($pdf);
	}
	
	public function setPdfParent(&$pdf)
	{
		$this->pdf = &$pdf;
	}
	
	public function setOnlyLeft()
	{
		$this->value['text-align'] = 'left';
		$this->onlyLeft = true;
	}

	public function getOldValues()
	{
		return isset($this->table[count($this->table)-1]) ? $this->table[count($this->table)-1] : $this->value;
	}
	
	/**
	* d�finit la fonte par d�faut si aucun fonte n'est sp�cifi�e, ou si la fonte demand�e n'existe pas
	*
	* @param	string	nom de la fonte par defaut. si null : Arial pour fonte non sp�cifi�e, et erreur pour fonte non existante
	* @return	string	nom de l'ancienne fonte par defaut
	*/
	public function setDefaultFont($default = null)
	{
		$old = $this->defaultFont;
		$this->defaultFont = $default;
		if ($default) $this->value['font-family'] = $default;
		return $old;
	}
	
 	/**
	 * Initialisation du style
	 *
	 * @return	null
	 */
	protected function init()
	{
		global $webcolor;
		$this->htmlColor = &$webcolor;
		
		$this->table = array();
		$this->value = array();
		$this->initStyle();
		
		// initialisation des styles sans h�ritages
		$this->resetStyle();
	}
	
	public function initStyle()
	{
 		$this->value['id_balise']			= 'body';		// balise
		$this->value['id_name']				= null;			// name
		$this->value['id_id']				= null;			// id
		$this->value['id_class']			= null;			// class
		$this->value['id_lst']				= array('*');	// lst de dependance
		$this->value['mini-size']			= 1.;			// rapport de taille	sp�cifique aux sup, sub
		$this->value['mini-decal']			= 0;			// rapport de position	sp�cifique aux sup, sub
		$this->value['font-family']			= 'Arial';
		$this->value['font-bold']			= false;
		$this->value['font-italic']			= false;
		$this->value['font-underline']		= false;
		$this->value['font-overline']		= false;
		$this->value['font-linethrough']	= false;
		$this->value['text-transform']		= 'none';
		$this->value['font-size']			= $this->ConvertToMM('10pt');
		$this->value['text-indent']			= 0;
		$this->value['text-align']			= 'left';
		$this->value['vertical-align']		= 'middle';
		$this->value['line-height']			= 'normal';

		$this->value['position']			= null;
		$this->value['x']					= null;
		$this->value['y']					= null;
		$this->value['width']				= 0;
		$this->value['height']				= 0;
		$this->value['top']					= null;
		$this->value['right']				= null;
		$this->value['bottom']				= null;
		$this->value['left']				= null;
		$this->value['float']				= null;
		$this->value['display']				= null;
		$this->value['rotate']				= null;
		$this->value['overflow']			= 'visible';
		
		$this->value['color']				= array(0, 0, 0);
		$this->value['background']			= array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
		$this->value['border']				= array();
		$this->value['padding']				= array();
		$this->value['margin']				= array();
		$this->value['margin-auto']			= false;

		$this->value['list-style-type']		= '';
		$this->value['list-style-image']	= '';

		$this->value['xc']					= null;
		$this->value['yc']					= null;
	}
	
	/**
	 * Initialisation des styles sans h�ritages
	 *
	 * @param	string	balise HTML
	 * @return	null
	 */
	public function resetStyle($balise = '')
	{
		$collapse = isset($this->value['border']['collapse']) ? $this->value['border']['collapse'] : false;
		if (!in_array($balise, array('tr', 'td', 'th', 'thead', 'tbody', 'tfoot'))) $collapse = false;
		
		$this->value['position']			= null;
		$this->value['x']					= null;
		$this->value['y']					= null;
		$this->value['width']				= 0;
		$this->value['height']				= 0;
		$this->value['top']					= null;
		$this->value['right']				= null;
		$this->value['bottom']				= null;
		$this->value['left']				= null;
		$this->value['float']				= null;
		$this->value['display']				= null;
		$this->value['rotate']				= null;
		$this->value['overflow']			= 'visible';
		$this->value['background']			= array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
		$this->value['border']	= array(
									't' => $this->readBorder('none'),
									'r' => $this->readBorder('none'),
									'b' => $this->readBorder('none'),
									'l' => $this->readBorder('none'),
									'radius' => array(
										'tl' => array(0, 0),
										'tr' => array(0, 0),
										'br' => array(0, 0),
										'bl' => array(0, 0)
									),
									'collapse' => $collapse,
								);

		if (!in_array($balise, array('h1', 'h2', 'h3', 'h4', 'h5', 'h6')))
			$this->value['margin']	= array('t'=>0,'r'=>0,'b'=>0,'l'=>0);
		
		if ($balise=='p')
		{
			$this->value['margin']['t'] = null;
			$this->value['margin']['b'] = null;
		}
		$this->value['margin-auto'] = false;
		
		if (in_array($balise, array('div', 'fieldset')))
			$this->value['vertical-align']	 = 'top';

		if (in_array($balise, array('fieldset', 'legend')))
		{
			$radius = $this->ConvertToMM('5px');
			$this->value['border']	= array(
									't' => $this->readBorder('solid 1px #000000'),
									'r' => $this->readBorder('solid 1px #000000'),
									'b' => $this->readBorder('solid 1px #000000'),
									'l' => $this->readBorder('solid 1px #000000'),
									'radius' => array(),
									'collapse' => false,
			);
			
			$this->value['border']['radius'] = array(
						'tl' => array($radius, $radius),
						'tr' => array($radius, $radius),
						'br' => array($radius, $radius),
						'bl' => array($radius, $radius));
    		}

		if (in_array($balise, array('ul', 'li')))
		{
			$this->value['list-style-type']		= '';
			$this->value['list-style-image']	= '';
		}

		if (!in_array($balise, array('tr', 'td')))
		{
			$this->value['padding']	= array(
									't' => 0,
									'r' => 0,
									'b' => 0,
									'l' => 0
								);
		}
		else
		{
			$this->value['padding']	= array(
									't' => $this->ConvertToMM('1px'),
									'r' => $this->ConvertToMM('1px'),
									'b' => $this->ConvertToMM('1px'),
									'l' => $this->ConvertToMM('1px')
								);
		}
		
		if ($balise=='hr')
		{
			$this->value['border']	= array(
									't' => $this->readBorder('solid 1px #000000'),
									'r' => $this->readBorder('solid 1px #000000'),
									'b' => $this->readBorder('solid 1px #000000'),
									'l' => $this->readBorder('solid 1px #000000'),
									'radius' => array(
										'tl' => array(0, 0),
										'tr' => array(0, 0),
										'br' => array(0, 0),
										'bl' => array(0, 0)
									),
									'collapse' => false,
								);
			$this->ConvertBackground('#FFFFFF', $this->value['background']);
		}

		$this->value['xc']					= null;
		$this->value['yc']					= null;
	}
	
	/**
	 * Initialisation de la font PDF
	 *
	 * @return	null
	 */
	public function FontSet()
	{
		$family = strtolower($this->value['font-family']);
		
		$b = ($this->value['font-bold']			? 'B' : '');
		$i = ($this->value['font-italic']		? 'I' : '');
		$u = ($this->value['font-underline']	? 'U' : '');
		$d = ($this->value['font-linethrough']	? 'D' : '');
		$o = ($this->value['font-overline']		? 'O' : '');
		
		if ($this->defaultFont)
		{
			$style = $b.$i;
			if($family=='arial')
				$family='helvetica';
			elseif($family=='symbol' || $family=='zapfdingbats')
				$style='';
			
			$fontkey = $family.$style;
			if (!$this->pdf->isLoadedFont($fontkey))
				$family = $this->defaultFont;
		}
		
		if($family=='arial')
			$family='helvetica';
		elseif($family=='symbol' || $family=='zapfdingbats')
			$style='';
		
		// taille en mm, � ramener en pt
		$size = $this->value['font-size'];
		$size = 72 * $size / 25.4;
				
		// application de la fonte
		$this->pdf->SetFont($family, $b.$i.$u.$d.$o, $this->value['mini-size']*$size);
		$this->pdf->setTextColorArray($this->value['color']);
		if ($this->value['background']['color'])
			$this->pdf->setFillColorArray($this->value['background']['color']);
		else
			$this->pdf->setFillColor(255);
	}

 	/**
	 * Monter d'un niveau dans l'historisation
	 *
	 * @return	null
	 */
	public function save()
	{
		$this->table[count($this->table)] = $this->value;
	}
	
 	/**
	 * Descendre d'un niveau dans l'historisation
	 *
	 * @return	null
	 */
	public function load()
	{
		if (count($this->table))
		{
			$this->value = $this->table[count($this->table)-1];
			unset($this->table[count($this->table)-1]);
		}
	}

	public function restorePosition()
	{
		if ($this->value['y']==$this->pdf->getY()) $this->pdf->setY($this->value['yc'], false);
	}
	
	public function setPosition()
	{
		$current_x = $this->pdf->getX();
		$current_y = $this->pdf->getY();
		$this->value['xc'] = $current_x;
		$this->value['yc'] = $current_y;
		
		if ($this->value['position']=='relative' || $this->value['position']=='absolute')
		{
			if ($this->value['right']!==null)
			{
				$x = $this->getLastWidth(true) - $this->value['right'] - $this->value['width'];
				if ($this->value['margin']['r']) $x-= $this->value['margin']['r'];
			}
			else
			{
				$x = $this->value['left'];
				if ($this->value['margin']['l']) $x+= $this->value['margin']['l'];
			}
			
			if ($this->value['bottom']!==null)
			{
				$y = $this->getLastHeight(true) - $this->value['bottom'] - $this->value['height'];
				if ($this->value['margin']['b']) $y-= $this->value['margin']['b'];
			}
			else
			{
				$y = $this->value['top'];
				if ($this->value['margin']['t']) $y+= $this->value['margin']['t'];
			}
			
			if ($this->value['position']=='relative')
			{
				$this->value['x'] = $current_x + $x;
				$this->value['y'] = $current_y + $y;
			}
			else
			{
				$this->value['x'] = $this->getLastAbsoluteX()+$x;
				$this->value['y'] = $this->getLastAbsoluteY()+$y;
			}
		}
		else
		{
			$this->value['x'] = $current_x;
			$this->value['y'] = $current_y;
			if ($this->value['margin']['l'])	$this->value['x']+= $this->value['margin']['l'];
			if ($this->value['margin']['t'])	$this->value['y']+= $this->value['margin']['t'];
		}
		
		$this->pdf->setXY($this->value['x'], $this->value['y']);
	}

 	/**
	 * Analyse un tableau de style provenant du parseurHTML
	 *
	 * @param	string	nom de la balise
	 * @param	array	tableau de style
	 * @return	null
	 */
	
	public function getSvgStyle($balise, &$param)
	{
		// preparation
		$balise = strtolower($balise);
		$id		= isset($param['id'])		? strtolower(trim($param['id']))	: null; if (!$id)	$id		= null;
		$name	= isset($param['name'])		? strtolower(trim($param['name']))	: null; if (!$name)	$name	= null;
		
		// lecture de la propriete classe
		$class = array();
		$tmp	= isset($param['class'])	? strtolower(trim($param['class'])) : '';
		$tmp = explode(' ', $tmp);
		foreach($tmp as $k => $v)
		{
			$v = trim($v);
			if ($v) $class[] = $v;
		}
		
		// identification de la balise et des styles direct qui pourraient lui �tre appliqu�s
		$this->value['id_balise']	= $balise;
		$this->value['id_name']		= $name;
		$this->value['id_id']		= $id;
		$this->value['id_class']	= $class;
		$this->value['id_lst']		= array();
		$this->value['id_lst'][] = '*';
		$this->value['id_lst'][] = $balise;
		if (!isset($this->value['svg']))
		{
			$this->value['svg'] = array(
				'stroke' 		=> null,
				'stroke-width'	=> $this->ConvertToMM('1pt'),
				'fill'			=> null,
				'fill-opacity'	=> null,
			);
		}
		
		if (count($class))
		{
			foreach($class as $v)
			{
				$this->value['id_lst'][] = '*.'.$v;
				$this->value['id_lst'][] = '.'.$v;
				$this->value['id_lst'][] = $balise.'.'.$v;
			}
		}
		if ($id)
		{
			$this->value['id_lst'][] = '*#'.$id;
			$this->value['id_lst'][] = '#'.$id;
			$this->value['id_lst'][] = $balise.'#'.$id;
		}
		
		// style CSS
		$styles = $this->getFromCSS();

		// on ajoute le style propre � la balise
		$styles = array_merge($styles, $param['style']);
		
		if (isset($styles['stroke']))		$this->value['svg']['stroke']		= $this->ConvertToColor($styles['stroke'],	$res);
		if (isset($styles['stroke-width']))	$this->value['svg']['stroke-width']	= $this->ConvertToMM($styles['stroke-width']);
		if (isset($styles['fill']))			$this->value['svg']['fill']			= $this->ConvertToColor($styles['fill'],	$res);
		if (isset($styles['fill-opacity']))	$this->value['svg']['fill-opacity']	= 1.*$styles['fill-opacity'];
		
		return $this->value['svg'];
	}
	
	/**
	 * Analyse un tableau de style provenant du parseurHTML
	 *
	 * @param	string	nom de la balise
	 * @param	array	tableau de style
	 * @param	array	tableau initialisant des styles
	 * @return	null
	 */
	public function analyse($balise, &$param, $heritage = null)
	{
		// preparation
		$balise = strtolower($balise);
		$id		= isset($param['id'])		? strtolower(trim($param['id']))	: null; if (!$id)	$id		= null;
		$name	= isset($param['name'])		? strtolower(trim($param['name']))	: null; if (!$name)	$name	= null;

		// lecture de la propriete classe
		$class = array();
		$tmp	= isset($param['class'])	? strtolower(trim($param['class']))	: '';
		$tmp = explode(' ', $tmp);
		foreach($tmp as $k => $v)
		{
			$v = trim($v);
			if ($v) $class[] = $v;
		}

		// identification de la balise et des styles direct qui pourraient lui �tre appliqu�s
		$this->value['id_balise']	= $balise;
		$this->value['id_name']		= $name;
		$this->value['id_id']		= $id;
		$this->value['id_class']	= $class;
		$this->value['id_lst']		= array();
		$this->value['id_lst'][] = '*';
		$this->value['id_lst'][] = $balise;
		if (count($class))
		{
			foreach($class as $v)
			{
				$this->value['id_lst'][] = '*.'.$v;
				$this->value['id_lst'][] = '.'.$v;
				$this->value['id_lst'][] = $balise.'.'.$v;
			}
		}
		if ($id)
		{
			$this->value['id_lst'][] = '*#'.$id;
			$this->value['id_lst'][] = '#'.$id;
			$this->value['id_lst'][] = $balise.'#'.$id;
		}
		
		// style CSS
		$styles = $this->getFromCSS();

		// on ajoute le style propre � la balise
		$styles = array_merge($styles, $param['style']);
		if (isset($param['allwidth']) && !isset($styles['width'])) $styles['width'] = '100%';

		// mise � zero des styles non h�rit�s
		$this->resetStyle($balise);
		if ($heritage)
		{
			foreach($heritage as $he_nom => $he_val)
			{
				if (is_array($he_val))
				{
					foreach($he_val as $he2_nom => $he2_val)
						$this->value[$he_nom][$he2_nom] = $he2_val;
				}
				else
					$this->value[$he_nom] = $he_val;
			}
		}
		
		// interpreration des nouvelles valeurs
		$correct_width = false;
		$no_width = true;

		foreach($styles as $nom => $val)
		{
			switch($nom)
			{
				case 'font-family':
					$val = explode(',', $val);
					$val = trim($val[0]);

					if ($val) $this->value['font-family'] = $val;
					break;
				
				case 'font-weight':
					$this->value['font-bold'] = ($val=='bold');
					break;
				
				case 'font-style':
					$this->value['font-italic'] = ($val=='italic');
					break;
				
				case 'text-decoration':
					$val = explode(' ', $val);
					$this->value['font-underline']		= (in_array('underline',	$val));
					$this->value['font-overline']		= (in_array('overline',		$val));
					$this->value['font-linethrough']	= (in_array('line-through',	$val));
					break;
				
				case 'text-indent':
					$this->value['text-indent']			= $this->ConvertToMM($val);
					break;
				
				case 'text-transform':
					if (!in_array($val, array('none', 'capitalize', 'uppercase', 'lowercase'))) $val = 'none';
					$this->value['text-transform']		= $val;
					break;
				
				case 'font-size':
					$val = $this->ConvertToMM($val, $this->value['font-size']);
					if ($val) $this->value['font-size'] = $val;
					break;
				
				case 'color':
					$res = null;
					$this->value['color'] = $this->ConvertToColor($val, $res);
					
					if ($balise=='hr')
					{
						$this->value['border']['l']['color'] = $this->value['color'];
						$this->value['border']['t']['color'] = $this->value['color'];
						$this->value['border']['r']['color'] = $this->value['color'];
						$this->value['border']['b']['color'] = $this->value['color'];
					}
					break;
				
				case 'text-align':
					$val = strtolower($val);
					if (!in_array($val, array('left', 'right', 'center', 'justify', 'li_right'))) $val = 'left';
					$this->value['text-align'] = $val;
					break;
				
				case 'vertical-align':
					$this->value['vertical-align'] = $val;
					break;
				
				case 'width':
					$this->value['width'] = $this->ConvertToMM($val, $this->getLastWidth());
					if ($this->value['width'] && substr($val, -1)=='%') $correct_width=true;
					$no_width = false;
					break;
				
				case 'height':
					$this->value['height'] = $this->ConvertToMM($val, $this->getLastHeight());
					break;
				
				case 'line-height':
					if (preg_match('/^[0-9\.]+$/isU', $val)) $val = floor($val*100).'%';
					$this->value['line-height'] = $val;
					break;
				
				case 'rotate':
					if (!in_array($val, array(0, -90, 90, 180, 270, -180, -270))) $val = null;
					if ($val<0) $val+= 360;
					$this->value['rotate'] = $val;
					break;
				
				case 'overflow':
					if (!in_array($val, array('visible', 'hidden'))) $val = 'visible';
					$this->value['overflow'] = $val;
					break;
				
				case 'padding':
					$val = explode(' ', $val);
					foreach($val as $k => $v)
					{
						$v = trim($v);
						if ($v!='') $val[$k] = $v;
						else	unset($val[$k]);
					}
					$val = array_values($val);
					$this->duplicateBorder($val);

					$this->value['padding']['t'] = $this->ConvertToMM($val[0], 0);
					$this->value['padding']['r'] = $this->ConvertToMM($val[1], 0);
					$this->value['padding']['b'] = $this->ConvertToMM($val[2], 0);
					$this->value['padding']['l'] = $this->ConvertToMM($val[3], 0);
					break;
				
				case 'padding-top':
					$this->value['padding']['t'] = $this->ConvertToMM($val, 0);
					break;

				case 'padding-right':
					$this->value['padding']['r'] = $this->ConvertToMM($val, 0);
					break;

				case 'padding-bottom':
					$this->value['padding']['b'] = $this->ConvertToMM($val, 0);
					break;

				case 'padding-left':
					$this->value['padding']['l'] = $this->ConvertToMM($val, 0);
					break;
				
				case 'margin':
					if ($val=='auto')
					{
						$this->value['margin-auto'] = true;
						break;
					}
					$val = explode(' ', $val);
					foreach($val as $k => $v)
					{
						$v = trim($v);
						if ($v!='') $val[$k] = $v;
						else	unset($val[$k]);
					}
					$val = array_values($val);
					$this->duplicateBorder($val);

					$this->value['margin']['t'] = $this->ConvertToMM($val[0], 0);
					$this->value['margin']['r'] = $this->ConvertToMM($val[1], 0);
					$this->value['margin']['b'] = $this->ConvertToMM($val[2], 0);
					$this->value['margin']['l'] = $this->ConvertToMM($val[3], 0);
					break;
				
				case 'margin-top':
					$this->value['margin']['t'] = $this->ConvertToMM($val, 0);
					break;

				case 'margin-right':
					$this->value['margin']['r'] = $this->ConvertToMM($val, 0);
					break;

				case 'margin-bottom':
					$this->value['margin']['b'] = $this->ConvertToMM($val, 0);
					break;

				case 'margin-left':
					$this->value['margin']['l'] = $this->ConvertToMM($val, 0);
					break;

				case 'border':
					$val = $this->readBorder($val);
					$this->value['border']['t'] = $val;
					$this->value['border']['r'] = $val;
					$this->value['border']['b'] = $val;
					$this->value['border']['l'] = $val;
					break;
				
				case 'border-style':
					$val = explode(' ', $val);
					foreach($val as $val_k => $val_v)
						if (!in_array($val_v, array('solid', 'dotted', 'dashed')))
							$val[$val_k] = null;
					$this->duplicateBorder($val);
					
					if ($val[0]) $this->value['border']['t']['type'] = $val[0];
					if ($val[1]) $this->value['border']['r']['type'] = $val[1];
					if ($val[2]) $this->value['border']['b']['type'] = $val[2];
					if ($val[3]) $this->value['border']['l']['type'] = $val[3];
					break;

				case 'border-top-style':
					if (in_array($val, array('solid', 'dotted', 'dashed')))
						$this->value['border']['t']['type'] = $val;
					break;

				case 'border-right-style':
					if (in_array($val, array('solid', 'dotted', 'dashed')))
						$this->value['border']['r']['type'] = $val;
					break;

				case 'border-bottom-style':
					if (in_array($val, array('solid', 'dotted', 'dashed')))
						$this->value['border']['b']['type'] = $val;
					break;

				case 'border-left-style':
					if (in_array($val, array('solid', 'dotted', 'dashed')))
						$this->value['border']['l']['type'] = $val;
					break;

				case 'border-color':
					$res = false;
					$val = preg_replace('/,[\s]+/', ',', $val);
					$val = explode(' ', $val);

					foreach($val as $val_k => $val_v)
					{
							$val[$val_k] = $this->ConvertToColor($val_v, $res);
							if (!$res) $val[$val_k] = null;
					}
					$this->duplicateBorder($val);

					if (is_array($val[0])) $this->value['border']['t']['color'] = $val[0];
					if (is_array($val[1])) $this->value['border']['r']['color'] = $val[1];
					if (is_array($val[2])) $this->value['border']['b']['color'] = $val[2];
					if (is_array($val[3])) $this->value['border']['l']['color'] = $val[3];
					
					break;

				case 'border-top-color':
					$res = false;
					$val = $this->ConvertToColor($val, $res);
					if ($res) $this->value['border']['t']['color'] = $val;
					break;

				case 'border-right-color':
					$res = false;
					$val = $this->ConvertToColor($val, $res);
					if ($res) $this->value['border']['r']['color'] = $val;
					break;

				case 'border-bottom-color':
					$res = false;
					$val = $this->ConvertToColor($val, $res);
					if ($res) $this->value['border']['b']['color'] = $val;
					break;

				case 'border-left-color':
					$res = false;
					$val = $this->ConvertToColor($val, $res);
					if ($res) $this->value['border']['l']['color'] = $val;
					break;
				
				case 'border-width':
					$val = explode(' ', $val);
					foreach($val as $val_k => $val_v)
					{
							$val[$val_k] = $this->ConvertToMM($val_v, 0);
					}
					$this->duplicateBorder($val);
					
					if ($val[0]) $this->value['border']['t']['width'] = $val[0];
					if ($val[1]) $this->value['border']['r']['width'] = $val[1];
					if ($val[2]) $this->value['border']['b']['width'] = $val[2];
					if ($val[3]) $this->value['border']['l']['width'] = $val[3];
					break;

				case 'border-top-width':
					$val = $this->ConvertToMM($val, 0);
					if ($val) $this->value['border']['t']['width'] = $val;
					break;

				case 'border-right-width':
					$val = $this->ConvertToMM($val, 0);
					if ($val) $this->value['border']['r']['width'] = $val;
					break;

				case 'border-bottom-width':
					$val = $this->ConvertToMM($val, 0);
					if ($val) $this->value['border']['b']['width'] = $val;
					break;

				case 'border-left-width':
					$val = $this->ConvertToMM($val, 0);
					if ($val) $this->value['border']['l']['width'] = $val;
					break;
				
				case 'border-collapse':
					if ($balise=='table') $this->value['border']['collapse'] = ($val=='collapse');
					break;
				
				case 'border-radius':
					$val = explode('/', $val); if (count($val)>2) break;

					$val_h = $this->ConvertToRadius(trim($val[0]));
					if (count($val_h)<1 || count($val_h)>4) break;
					if (!isset($val_h[1])) $val_h[1] = $val_h[0];
					if (!isset($val_h[2])) $val_h = array($val_h[0], $val_h[0], $val_h[1], $val_h[1]);
					if (!isset($val_h[3])) $val_h[3] = $val_h[1];
					
					if (isset($val[1]))
					{
						$val_v = $this->ConvertToRadius(trim($val[1]));
						if (count($val_v)<1 || count($val_v)>4) break;
						if (!isset($val_v[1])) $val_v[1] = $val_v[0];
						if (!isset($val_v[2])) $val_v = array($val_v[0], $val_v[0], $val_v[1], $val_v[1]);
						if (!isset($val_v[3])) $val_v[3] = $val_v[1];
					}
					else
						$val_v = $val_h;
					
					$this->value['border']['radius'] = array(
								'tl' => array($val_h[0], $val_v[0]),
								'tr' => array($val_h[1], $val_v[1]),
								'br' => array($val_h[2], $val_v[2]),
								'bl' => array($val_h[3], $val_v[3])
							);
					break;
				
				case 'border-top-left-radius':
					$val = $this->ConvertToRadius($val);
					if (count($val)<1 || count($val)>2) break;
					$this->value['border']['radius']['tl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
					break;
				
				case 'border-top-right-radius':
					$val = $this->ConvertToRadius($val);
					if (count($val)<1 || count($val)>2) break;
					$this->value['border']['radius']['tr'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
					break;

				case 'border-bottom-right-radius':
					$val = $this->ConvertToRadius($val);
					if (count($val)<1 || count($val)>2) break;
					$this->value['border']['radius']['br'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
					break;

				case 'border-bottom-left-radius':
					$val = $this->ConvertToRadius($val);
					if (count($val)<1 || count($val)>2) break;
					$this->value['border']['radius']['bl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
					break;

				case 'border-top':
					$this->value['border']['t'] = $this->readBorder($val);
					break;

				case 'border-right':
					$this->value['border']['r'] = $this->readBorder($val);
					break;

				case 'border-bottom':
					$this->value['border']['b'] = $this->readBorder($val);
					break;

				case 'border-left':
					$this->value['border']['l'] = $this->readBorder($val);
					break;
				
				case 'background-color':
					$this->value['background']['color'] = $this->ConvertBackgroundColor($val);
					break;

				case 'background-image':
					$this->value['background']['image'] = $this->ConvertBackgroundImage($val);
					break;

				case 'background-position':
					$res = null;
					$this->value['background']['position'] = $this->ConvertBackgroundPosition($val, $res);
					break;

				case 'background-repeat':
					$this->value['background']['repeat'] = $this->ConvertBackgroundRepeat($val);
					break;

				case 'background':
					$this->ConvertBackground($val, $this->value['background']);
					break;

				case 'position':
					if ($val=='absolute')		$this->value['position'] = 'absolute';
					else if ($val=='relative')	$this->value['position'] = 'relative';
					else						$this->value['position'] = null;
					break;

				case 'float':
					if ($val=='left')			$this->value['float'] = 'left';
					else if ($val=='right')		$this->value['float'] = 'right';
					else						$this->value['float'] = null;
					break;

				case 'display':
					if ($val=='inline')			$this->value['display'] = 'inline';
					else if ($val=='block')		$this->value['display'] = 'block';
					else if ($val=='none')		$this->value['display'] = 'none';
					else						$this->value['display'] = null;
					break;
				
				case 'top':
				case 'bottom':
				case 'left':
				case 'right':
					$this->value[$nom] = $val;
					break;

				case 'list-style':
				case 'list-style-type':
				case 'list-style-image':
					if ($nom=='list-style') $nom = 'list-style-type';
					$this->value[$nom] = $val;
					break;
				
				default:
					break;
			}
		}

		$return = true;

		if ($this->value['margin']['t']===null) $this->value['margin']['t'] = $this->value['font-size'];
		if ($this->value['margin']['b']===null) $this->value['margin']['b'] = $this->value['font-size'];
		
		if ($this->onlyLeft) $this->value['text-align'] = 'left';
		
		// correction de la largeur pour correspondre au mod�le de boite quick
		if ($no_width && in_array($balise, array('div', 'fieldset')) && $this->value['position']!='absolute')
		{
			$this->value['width'] = $this->getLastWidth();
			$this->value['width']-= $this->value['margin']['l'] + $this->value['margin']['r'];
		}
		else
		{
			if ($correct_width)
			{
				if (!in_array($balise, array('table', 'div', 'fieldset', 'hr')))
				{
					$this->value['width']-= $this->value['padding']['l'] + $this->value['padding']['r'];
					$this->value['width']-= $this->value['border']['l']['width'] + $this->value['border']['r']['width'];
				}
				if (in_array($balise, array('th', 'td')))
				{
					$this->value['width']-= $this->ConvertToMM(isset($param['cellspacing']) ? $param['cellspacing'] : '2px');
					$return = false;
				}
				if ($this->value['width']<0) $this->value['width']=0;
			}
			else
			{
				if ($this->value['width'])
				{
					if ($this->value['border']['l']['width'])	$this->value['width']	+= $this->value['border']['l']['width'];
					if ($this->value['border']['r']['width'])	$this->value['width']	+= $this->value['border']['r']['width'];
					if ($this->value['padding']['l'])			$this->value['width']	+= $this->value['padding']['l'];
					if ($this->value['padding']['r'])			$this->value['width']	+= $this->value['padding']['r'];
				}
			}
		}
		if ($this->value['height'])
		{
			if ($this->value['border']['b']['width']) { $this->value['height']	+= $this->value['border']['b']['width']; }
			if ($this->value['border']['t']['width']) { $this->value['height']	+= $this->value['border']['t']['width']; }
			if ($this->value['padding']['b'])			$this->value['height']	+= $this->value['padding']['b'];
			if ($this->value['padding']['t'])			$this->value['height']	+= $this->value['padding']['t'];
		}
		
		if ($this->value['top']!=null)		$this->value['top']		= $this->ConvertToMM($this->value['top'],		$this->getLastHeight(true));
		if ($this->value['bottom']!=null)	$this->value['bottom']	= $this->ConvertToMM($this->value['bottom'],	$this->getLastHeight(true));
		if ($this->value['left']!=null)		$this->value['left']	= $this->ConvertToMM($this->value['left'],		$this->getLastWidth(true));
		if ($this->value['right']!=null)	$this->value['right']	= $this->ConvertToMM($this->value['right'],		$this->getLastWidth(true));
		
		if ($this->value['top'] && $this->value['bottom'] && $this->value['height'])	$this->value['bottom']	= null;
		if ($this->value['left'] && $this->value['right'] && $this->value['width'])		$this->value['right']	= null;
		
		return $return;
	}
	
 	/**
	 * R�cup�ration de la hauteur de ligne courante
	 *
	 * @return	float	hauteur en mm
	 */
	public function getLineHeight()
	{
		$val = $this->value['line-height'];
		if ($val=='normal') $val = '108%';
		return $this->ConvertToMM($val, $this->value['font-size']);
	}
	
 	/**
	 * R�cup�ration de la largeur de l'objet parent
	 *
	 * @return	float	largeur
	 */
	public function getLastWidth($mode = false)
	{
		for($k=count($this->table)-1; $k>=0; $k--)
		{
			if ($this->table[$k]['width'])
			{
				$w = $this->table[$k]['width'];
				if ($mode)
				{
					$w+= $this->table[$k]['border']['l']['width'] + $this->table[$k]['padding']['l'] + 0.02;
					$w+= $this->table[$k]['border']['r']['width'] + $this->table[$k]['padding']['r'] + 0.02;
				}
				return $w;
			}
		}
		return $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
	}

 	/**
	 * R�cup�ration de la hauteur de l'objet parent
	 *
	 * @return	float	hauteur
	 */
	public function getLastHeight($mode = false)
	{
		for($k=count($this->table)-1; $k>=0; $k--)
		{
			if ($this->table[$k]['height'])
			{
				$h = $this->table[$k]['height'];
				if ($mode)
				{
					$h+= $this->table[$k]['border']['t']['width'] + $this->table[$k]['padding']['t'] + 0.02;
					$h+= $this->table[$k]['border']['b']['width'] + $this->table[$k]['padding']['b'] + 0.02;
				}
				return $h;
			}
		}
		return $this->pdf->getH() - $this->pdf->gettMargin() - $this->pdf->getbMargin();
	}
	
	public function getFloat()
	{
		if ($this->value['float']=='left')	return 'left';
		if ($this->value['float']=='right')	return 'right';
		return null;
	}
	
	public function getLastValue($key)
	{
		$nb = count($this->table);
		if ($nb>0)
			return $this->table[$nb-1][$key];
		return null;
	}

	protected function getLastAbsoluteX()
	{
		for($k=count($this->table)-1; $k>=0; $k--)
		{
			if ($this->table[$k]['x'] && $this->table[$k]['position']) return $this->table[$k]['x'];
		}
		return $this->pdf->getlMargin();
	}
	
	protected function getLastAbsoluteY()
	{
		for($k=count($this->table)-1; $k>=0; $k--)
		{
			if ($this->table[$k]['y'] && $this->table[$k]['position']) return $this->table[$k]['y'];
		}
		return $this->pdf->gettMargin();
	}
	
	/**
	 * R�cup�ration des propri�t�s CSS de la balise en cours
	 *
	 * @return	array()		tableau des propri�t�s CSS
	 */
	protected function getFromCSS()
	{
		$styles	= array();	// style � appliquer
		$getit	= array();	// styles � r�cuperer

		// identification des styles direct, et ceux des parents
		$lst = array();
		$lst[] = $this->value['id_lst'];
		for($i=count($this->table)-1; $i>=0; $i--) $lst[] = $this->table[$i]['id_lst'];

		// identification des styles � r�cuperer
		foreach($this->css_keys as $key => $num)
			if ($this->getReccursiveStyle($key, $lst))
				$getit[$key] = $num;

		// si des styles sont � recuperer
		if (count($getit))
		{
			// on les r�cup�re, mais dans l'odre de d�finition, afin de garder les priorit�s
			asort($getit);
			foreach($getit as $key => $val) $styles = array_merge($styles, $this->css[$key]);
		}
		
		return $styles;
	}
	
	/**
	 * Identification des styles � r�cuperer, en fonction de la balise et de ses parents
	 *
	 * @param	string		clef CSS � analyser
	 * @param	array()		tableau des styles direct, et ceux des parents
	 * @param	string		prochaine etape
	 * @return	boolean		clef autoris�e ou non
	 */
	protected function getReccursiveStyle($key, $lst, $next = null)
	{
		// si propchaine etape, on construit les valeurs
		if ($next!==null)
		{
			if ($next) $key = trim(substr($key, 0, -strlen($next))); // on el�ve cette etape
			unset($lst[0]);
			if (!count($lst)) return false; // pas d'etape possible
			$lst = array_values($lst);
		}
		
		// pour chaque style direct possible de l'etape en cours
		foreach($lst[0] as $nom)
		{
			if ($key==$nom) return true; // si la clef conrrespond => ok
			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
		}

		// si on est pas � la premiere etape, on doit analyse toutes les sous etapes
		if ($next!==null && $this->getReccursiveStyle($key, $lst, '')) return true;
		
		// aucun style trouv�
		return false;
	}
	
	/**
	 * Analyse d'une propri�t� Border
	 *
	 * @param	string		propri�t� border
	 * @return	array()		propri�t� d�cod�e
	 */
	public function readBorder($val)
	{
		$none = array('type' => 'none', 'width' => 0, 'color' => array(0, 0, 0));

		// valeurs par d�fault
		$type	= 'solid';
		$width	= $this->ConvertToMM('1pt');
		$color	= array(0, 0, 0);

		// nettoyage des valeurs
		$val = explode(' ', $val);
		foreach($val as $k => $v)
		{
			$v = trim($v);
			if ($v)	$val[$k] = $v;
			else	unset($val[$k]);
		}
		$val = array_values($val);
		// identification des valeurs
		$res = null;
		foreach($val as $key)
		{
			if ($key=='none' || $key=='hidden') return $none;
			
			if ($this->ConvertToMM($key)!==null)
				$width = $this->ConvertToMM($key);
			else if (in_array($key, array('solid', 'dotted', 'dashed', 'double')))
				$type = $key;
			else
			{
				$tmp = $this->ConvertToColor($key, $res);
				if ($res) $color = $tmp;
			}
		}
		if (!$width) return $none;
		return array('type' => $type, 'width' => $width, 'color' => $color);
	}
	
	protected function duplicateBorder(&$val)
	{
		if (count($val)==1)
		{
			$val[1] = $val[0];
			$val[2] = $val[0];
			$val[3] = $val[0];
		}
		else if (count($val)==2)
		{
			$val[2] = $val[0];
			$val[3] = $val[1];
		}
		else if (count($val)==3)
		{
			$val[3] = $val[1];
		}
	}

	public function ConvertBackground($stl, &$res)
	{
		// Image
		$text = '/url\(([^)]*)\)/isU';
		if (preg_match($text, $stl, $match))
		{
			$res['image'] = $this->ConvertBackgroundImage($match[0]);
			$stl = preg_replace($text, '', $stl);
			$stl = preg_replace('/[\s]+/', ' ', $stl);
		}
		
		// protection des espaces
		$stl = preg_replace('/,[\s]+/', ',', $stl);
		$lst = explode(' ', $stl);
		
		$pos = '';
		foreach($lst as $val)
		{
			$ok = false;
			$color = $this->ConvertToColor($val, $ok);
			
			if ($ok)
			{
				$res['color'] = $color;
			}
			else if ($val=='transparent')
			{
				$res['color'] = null;
			}
			else
			{
				$repeat = $this->ConvertBackgroundRepeat($val);
				if ($repeat)
				{
					$res['repeat'] = $repeat;
				}
				else
				{
					$pos.= ($pos ? ' ' : '').$val;
				}
			}
		}
		if ($pos)
		{
			$pos = $this->ConvertBackgroundPosition($pos, $ok);
			if ($ok) $res['position'] = $pos;
		}
	}

	public function ConvertBackgroundColor($val)
	{
		$res = null;
		if ($val=='transparent')	return null;
		else						return $this->ConvertToColor($val, $res);
	}

	public function ConvertBackgroundImage($val)
	{
		if ($val=='none')
			return null;
		else if (preg_match('/^url\(([^)]*)\)$/isU', $val, $match))
			return $match[1];
		else
			return null;
	}
	
	public function ConvertBackgroundPosition($val, &$res)
	{
		$val = explode(' ', $val);
		if (count($val)<2)
		{
			if (!$val[0]) return null;
			$val[1] = 'center';
		}
		if (count($val)>2) return null;

		$x = 0;
		$y = 0;
		$res = true;
		
		if ($val[0]=='left')		$x = '0%';
		else if ($val[0]=='center')	$x = '50%';
		else if ($val[0]=='right')	$x = '100%';
		else if ($val[0]=='top')	$y = '0%';
		else if ($val[0]=='bottom')	$y = '100%';
		else if (preg_match('/^[-]?[0-9\.]+%$/isU',	$val[0])) $x = $val[0];
		else if ($this->ConvertToMM($val[0])) $x = $this->ConvertToMM($val[0]);
		else $res = false;
		
		if ($val[1]=='left')		$x = '0%';
		else if ($val[1]=='right')	$x = '100%';
		else if ($val[1]=='top')	$y = '0%';
		else if ($val[1]=='center')	$y = '50%';
		else if ($val[1]=='bottom')	$y = '100%';
		else if (preg_match('/^[-]?[0-9\.]+%$/isU',	$val[1])) $y = $val[1];
		else if ($this->ConvertToMM($val[1])) $y = $this->ConvertToMM($val[1]);
		else $res = false;

		$val[0] = $x;
		$val[1] = $y;
		
		return $val;
	}
	
 	public function ConvertBackgroundRepeat($val)
	{
		switch($val)
		{
			case 'repeat':
				return array(true, true);
			case 'repeat-x':
				return array(true, false);
			case 'repeat-y':
				return array(false, true);
			case 'no-repeat':
				return array(false, false);
		}
		return null;
	}
 	/**
	 * Convertir une longueur en mm
	 *
	 * @param	string			longueur, avec unit�, � convertir
	 * @param	float			longueur du parent
	 * @return	float			longueur exprim�e en mm
	 */
	public function ConvertToMM($val, $old=0.)
	{
		$val = trim($val);
		if (preg_match('/^[0-9\.\-]+$/isU', $val))			$val.= 'px';
		if (preg_match('/^[0-9\.\-]+px$/isU', $val))		$val = 25.4/96. * str_replace('px', '', $val);
		else if (preg_match('/^[0-9\.\-]+pt$/isU', $val))	$val = 25.4/72. * str_replace('pt', '', $val);
		else if (preg_match('/^[0-9\.\-]+in$/isU', $val))	$val = 25.4 * str_replace('in', '', $val);
		else if (preg_match('/^[0-9\.\-]+mm$/isU', $val))	$val = 1.*str_replace('mm', '', $val);
		else if (preg_match('/^[0-9\.\-]+%$/isU', $val))	$val = 1.*$old*str_replace('%', '', $val)/100.;
		else												$val = null;

		return $val;
	}
	
	public function ConvertToRadius($val)
	{
		$val = explode(' ', $val);
		foreach($val as $k => $v)
		{
			$v = trim($v);
			if ($v)
			{
				$v = $this->ConvertToMM($v, 0);
				if ($v!==null)
					$val[$k] = $v;
				else
					unset($val[$k]);
			}
			else	unset($val[$k]);
		}
		return array_values($val);
	}
	
 	/**
	 * D�composition d'un code couleur HTML
	 *
	 * @param	string			couleur au format CSS
	 * @return	array(r, v, b)	couleur exprim� par ses comporantes R, V, B, de 0 � 255.
	 */
	public function ConvertToColor($val, &$res)
	{
		
		$val = trim($val);
		$res = true;
		
		if (strtolower($val)=='transparent') return array(null, null, null);
		if (isset($this->htmlColor[strtolower($val)]))
		{
			$val = $this->htmlColor[strtolower($val)];
			$r = floatVal(hexdec(substr($val, 0, 2)));
			$v = floatVal(hexdec(substr($val, 2, 2)));
			$b = floatVal(hexdec(substr($val, 4, 2)));
			$col = array($r, $v, $b);
		}
		elseif (preg_match('/^#[0-9A-Fa-f]{6}$/isU', $val))
		{
			$r = floatVal(hexdec(substr($val, 1, 2)));
			$v = floatVal(hexdec(substr($val, 3, 2)));
			$b = floatVal(hexdec(substr($val, 5, 2)));
			$col = array($r, $v, $b);
		}
		elseif (preg_match('/^#[0-9A-F]{3}$/isU', $val))
		{
			$r = floatVal(hexdec(substr($val, 1, 1).substr($val, 1, 1)));
			$v = floatVal(hexdec(substr($val, 2, 1).substr($val, 2, 1)));
			$b = floatVal(hexdec(substr($val, 3, 1).substr($val, 3, 1)));
			$col = array($r, $v, $b);
		}
		elseif (preg_match('/rgb\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $val, $match))
		{
			$r = $this->ConvertSubColor($match[1]);
			$v = $this->ConvertSubColor($match[2]);
			$b = $this->ConvertSubColor($match[3]);
			$col = array($r*255., $v*255., $b*255.);
		}
		elseif (preg_match('/cmyk\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $val, $match))
		{
			$c = $this->ConvertSubColor($match[1]);
			$m = $this->ConvertSubColor($match[2]);
			$y = $this->ConvertSubColor($match[3]);
			$k = $this->ConvertSubColor($match[4]);
			$col = array($c*100., $m*100., $y*100., $k*100.);
		}
		else
		{
			$col = array(0., 0., 0.);
			$res = false;
		}
		
		return $col;
	}
	
	protected function ConvertSubColor($c)
	{
		if (substr($c, -1)=='%') $c = floatVal(substr($c, 0, -1))/100.;
		else
		{
			$c = floatVal($c);
			if ($c>1) $c = $c/255.;
		}
		return $c;
	}
	
	/**
	 * Analyser une feuille de style
	 *
	 * @param	string			code CSS
	 * @return	null
	 */
	protected function analyseStyle(&$code)
	{
		// on remplace tous les espaces, tab, \r, \n, par des espaces uniques
		$code = preg_replace('/[\s]+/', ' ', $code);

		// on enl�ve les commentaires
		$code = preg_replace('/\/\*.*?\*\//s', '', $code);

		// on analyse chaque style
		preg_match_all('/([^{}]+){([^}]*)}/isU', $code, $match);
		for($k=0; $k<count($match[0]); $k++)
		{
			// noms
			$noms	= strtolower(trim($match[1][$k]));
			
			// style, s�par� par des; => on remplie le tableau correspondant
			$styles	= trim($match[2][$k]);
			$styles = explode(';', $styles);
			$stl = array();
			foreach($styles as $style)
			{
				$tmp = explode(':', $style);
				if (count($tmp)>1)
				{
					$cod = $tmp[0]; unset($tmp[0]); $tmp = implode(':', $tmp);
					$stl[trim(strtolower($cod))] = trim($tmp);
				}
			}
			
			// d�composition des noms par les ,
			$noms = explode(',', $noms);
			foreach($noms as $nom)
			{
				$nom = trim($nom);
				// Si il a une fonction sp�cifique, comme :hover => on zap
				if (strpos($nom, ':')!==false) continue;
				if (!isset($this->css[$nom]))
					$this->css[$nom] = $stl;
				else
					$this->css[$nom] = array_merge($this->css[$nom], $stl);
				
			}
		}
		
		$this->css_keys = array_flip(array_keys($this->css));
	}
	
	/**
	 * Extraction des feuille de style du code HTML
	 *
	 * @param	string			code HTML
	 * @return	null
	 */
	public function readStyle(&$html)
	{
		$style = ' ';

		// extraction des balises link, et suppression de celles-ci dans le code HTML
		preg_match_all('/<link([^>]*)>/isU', $html, $match);
		$html = preg_replace('/<link[^>]*>/isU',	'', $html);
		$html = preg_replace('/<\/link[^>]*>/isU',	'', $html);
		
		// analyse de chaque balise
		foreach($match[1] as $code)
		{
			$tmp = array();
			// lecture des param�tres du type nom=valeur
			$prop = '([a-zA-Z0-9_]+)=([^"\'\s>]+)';
			preg_match_all('/'.$prop.'/is', $code, $match);
			for($k=0; $k<count($match[0]); $k++)
				$tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);

			// lecture des param�tres du type nom="valeur"
			$prop = '([a-zA-Z0-9_]+)=["]([^"]*)["]';
			preg_match_all('/'.$prop.'/is', $code, $match);
			for($k=0; $k<count($match[0]); $k++)
				$tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);

			// lecture des param�tres du type nom='valeur'
			$prop = "([a-zA-Z0-9_]+)=[']([^']*)[']";
			preg_match_all('/'.$prop.'/is', $code, $match);
			for($k=0; $k<count($match[0]); $k++)
				$tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);

			// si de type text/css => on garde
			if (isset($tmp['type']) && strtolower($tmp['type'])=='text/css' && isset($tmp['href']))
			{
				$content = @file_get_contents($tmp['href']);
				$url = $tmp['href'];
				if (strpos($url, 'http://')!==false)
				{
					$url = str_replace('http://', '', $url);
					$url = explode('/', $url);
					$url_main = 'http://'.$url[0].'/';
					$url_self = $url; unset($url_self[count($url_self)-1]); $url_self = 'http://'.implode('/', $url_self).'/';

					$content = preg_replace('/url\(([^\\\\][^)]*)\)/isU', 'url('.$url_self.'$1)', $content);
					$content = preg_replace('/url\((\\\\[^)]*)\)/isU', 'url('.$url_main.'$1)', $content);
				}
				else
				{
					// @todo
					// $content = preg_replace('/url\(([^)]*)\)/isU', 'url('.dirname($url).'/$1)', $content);
				}
				$style.= $content."\n";
			}
		}


		// extraction des balises style, et suppression de celles-ci dans le code HTML
		preg_match_all('/<style[^>]*>(.*)<\/style[^>]*>/isU', $html, $match);
		$html = preg_replace('/<style[^>]*>(.*)<\/style[^>]*>/isU', '', $html);

		// analyse de chaque balise
		foreach($match[1] as $code)
		{
			$code = str_replace('<!--', '', $code);
			$code = str_replace('-->', '', $code);
			$style.= $code."\n";
		}
		
		$this->analyseStyle($style);
	}
}