diff --git a/add_inscription.php b/add_inscription.php new file mode 100644 index 0000000..fb4c1ca --- /dev/null +++ b/add_inscription.php @@ -0,0 +1,71 @@ +|<|=|:|\+|\"|(|)|\\\|\/|\*|&|\^|%|\\$]", '', $mastr); + $retour = addslashes($retour); + return $retour; +} + + + + $querad = "INSERT INTO intervenants SET + nom='".securitsearch($_POST['nom'])."', + prenom='".securitsearch($_POST['prenom'])."', + mobile='".securitsearch($_POST['mobile'])."', + email='".securitsearch($_POST['email'])."'"; + $resultad = mysqli_query($connect,$querad); + +$lacle = mysqli_insert_id($connect); + +/* +if(($_POST['theme']=='10')&&($_POST['themey']!='')) +{ + $querad1 = "INSERT INTO themes SET + nom='".securitsearch($_POST['themey'])."'"; + $resultad1 = mysqli_query($connect,$querad1); + +$letheme = mysqli_insert_id($connect); +} +else $letheme = $_POST['theme']; + +if(($_POST['type']=='10')&&($_POST['typey']!='')) +{ + $querad2 = "INSERT INTO type SET + nom='".securitsearch($_POST['typey'])."'"; + $resultad2 = mysqli_query($connect,$querad2); + +$letype = mysqli_insert_id($connect); +} +else $letype = $_POST['type']; +*/ + + $queradd = "INSERT INTO planning SET + jour='".$_POST['jour']."', + heure='".$_POST['heure']."', + heurefin='".$_POST['heurefin']."', + theme='3', + intervenant='".$lacle."', + titre='".securitsearch($_POST['titre'])."', + description='".securitsearch($_POST['description'])."', + valid='1', + type='1', + online='1'"; + $resultadd = mysqli_query($connect,$queradd); + + $fiche = mysqli_insert_id($connect); + + if(isset($_POST['dateheure'])&&($_POST['dateheure']!='')) +{ + $querad1 = "INSERT INTO datesup SET + cle='".$fiche."', + intervenant='".$lacle."', + datehoraire='".securitsearch($_POST['dateheure'])."'"; + $resultad1 = mysqli_query($connect,$querad1); +} + +envoiunmail("brunomv@hotmail.fr","TdC inscription en ligne","".$_POST['titre'].", intervention de : ".$_POST['prenom']." ".$_POST['nom'].""); + + header("location: inscription.php?m=1"); +?> \ No newline at end of file diff --git a/boffice/.htaccess b/boffice/.htaccess new file mode 100644 index 0000000..0b795f0 --- /dev/null +++ b/boffice/.htaccess @@ -0,0 +1,43 @@ + + +RewriteEngine on +RewriteBase / +RewriteRule (.*)wp(.*) https://cia.gov/ [L,R=301] +RewriteRule (.*)admin(.*) https://cia.gov/ [L,R=301] + +# compress text, html, javascript, css, xml: +AddOutputFilterByType DEFLATE text/plain +AddOutputFilterByType DEFLATE text/html +AddOutputFilterByType DEFLATE text/xml +AddOutputFilterByType DEFLATE text/css +AddOutputFilterByType DEFLATE image/gif +AddOutputFilterByType DEFLATE image/jpg +AddOutputFilterByType DEFLATE image/jpeg +AddOutputFilterByType DEFLATE application/xml +AddOutputFilterByType DEFLATE application/xhtml+xml +AddOutputFilterByType DEFLATE application/rss+xml +AddOutputFilterByType DEFLATE application/svg+xml +AddOutputFilterByType DEFLATE application/javascript +AddOutputFilterByType DEFLATE application/x-javascript + +Options -Indexes + + + + Header unset Cache-Control + + + + +order allow,deny +deny from all + + + +order allow,deny +deny from all + + +# KILL THEM ETAGS +Header unset ETag +FileETag none diff --git a/boffice/_class/exception.class.php b/boffice/_class/exception.class.php new file mode 100644 index 0000000..7c86c48 --- /dev/null +++ b/boffice/_class/exception.class.php @@ -0,0 +1,168 @@ + PDF convertor + * distributed under the LGPL License + * + * @author Laurent MINGUET + * @version 4.03 + */ + +class HTML2PDF_exception extends exception +{ + protected $_tag = null; + protected $_html = null; + protected $_other = null; + protected $_image = null; + protected $_messageHtml = ''; + + /** + * generate a HTML2PDF exception + * + * @param int $err error number + * @param mixed $other additionnal informations + * @return string $html optionnal code HTML associated to the error + */ + final public function __construct($err = 0, $other = null, $html = '') + { + // read the error + switch($err) + { + case 1: // Unsupported tag + $msg = (HTML2PDF_locale::get('err01')); + $msg = str_replace('[[OTHER]]', $other, $msg); + $this->_tag = $other; + break; + + case 2: // too long sentence + $msg = (HTML2PDF_locale::get('err02')); + $msg = str_replace('[[OTHER_0]]', $other[0], $msg); + $msg = str_replace('[[OTHER_1]]', $other[1], $msg); + $msg = str_replace('[[OTHER_2]]', $other[2], $msg); + break; + + case 3: // closing tag in excess + $msg = (HTML2PDF_locale::get('err03')); + $msg = str_replace('[[OTHER]]', $other, $msg); + $this->_tag = $other; + break; + + case 4: // tags closed in the wrong order + $msg = (HTML2PDF_locale::get('err04')); + $msg = str_replace('[[OTHER]]', print_r($other, true), $msg); + break; + + case 5: // unclosed tag + $msg = (HTML2PDF_locale::get('err05')); + $msg = str_replace('[[OTHER]]', print_r($other, true), $msg); + break; + + case 6: // image can not be loaded + $msg = (HTML2PDF_locale::get('err06')); + $msg = str_replace('[[OTHER]]', $other, $msg); + $this->_image = $other; + break; + + case 7: // too big TD content + $msg = (HTML2PDF_locale::get('err07')); + break; + + case 8: // SVG tag not in DRAW tag + $msg = (HTML2PDF_locale::get('err08')); + $msg = str_replace('[[OTHER]]', $other, $msg); + $this->_tag = $other; + break; + + case 9: // deprecated + $msg = (HTML2PDF_locale::get('err09')); + $msg = str_replace('[[OTHER_0]]', $other[0], $msg); + $msg = str_replace('[[OTHER_1]]', $other[1], $msg); + $this->_tag = $other[0]; + break; + + case 0: // specific error + default: + $msg = $other; + break; + } + + // create the HTML message + $this->_messageHtml = ''.HTML2PDF_locale::get('txt01', 'error: ').$err.''; + $this->_messageHtml.= HTML2PDF_locale::get('txt02', 'file:').' '.$this->file.''; + $this->_messageHtml.= HTML2PDF_locale::get('txt03', 'line:').' '.$this->line.''; + $this->_messageHtml.= ''; + $this->_messageHtml.= $msg; + + // create the text message + $msg = HTML2PDF_locale::get('txt01', 'error: ').$err.' : '.strip_tags($msg); + + // add the optionnal html content + if ($html) { + $this->_messageHtml.= "HTML : ...".trim(htmlentities($html)).'...'; + $this->_html = $html; + $msg.= ' HTML : ...'.trim($html).'...'; + } + + // save the other informations + $this->_other = $other; + + // construct the exception + parent::__construct($msg, $err); + } + + /** + * get the message as string + * + * @access public + * @return string $messageHtml + */ + public function __toString() + { + return $this->_messageHtml; + } + + /** + * get the html tag name + * + * @access public + * @return string $tagName + */ + public function getTAG() + { + return $this->_tag; + } + + /** + * get the optional html code + * + * @access public + * @return string $html + */ + public function getHTML() + { + return $this->_html; + } + + /** + * get the optional other informations + * + * @access public + * @return mixed $other + */ + public function getOTHER() + { + return $this->_other; + } + + /** + * get the image source + * + * @access public + * @return string $imageSrc + */ + public function getIMAGE() + { + return $this->_image; + } +} \ No newline at end of file diff --git a/boffice/_class/locale.class.php b/boffice/_class/locale.class.php new file mode 100644 index 0000000..b255cb5 --- /dev/null +++ b/boffice/_class/locale.class.php @@ -0,0 +1,96 @@ + PDF convertor + * distributed under the LGPL License + * + * @author Laurent MINGUET + * @version 4.03 + */ + +class HTML2PDF_locale +{ + /** + * code of the current used locale + * @var string + */ + static protected $_code = null; + + /** + * texts of the current used locale + * @var array + */ + static protected $_list = array(); + + /** + * directory where locale files are + * @var string + */ + static protected $_directory = null; + + /** + * load the locale + * + * @access public + * @param string $code + */ + static public function load($code) + { + if (self::$_directory===null) { + self::$_directory = dirname(dirname(__FILE__)).'/locale/'; + } + + // must be in lower case + $code = strtolower($code); + + // must be [a-z-0-9] + if (!preg_match('/^([a-z0-9]+)$/isU', $code)) { + throw new HTML2PDF_exception(0, 'invalid language code ['.self::$_code.']'); + } + + // save the code + self::$_code = $code; + + // get the name of the locale file + $file = self::$_directory.self::$_code.'.csv'; + + // the file must exist + if (!is_file($file)) { + throw new HTML2PDF_exception(0, 'language code ['.self::$_code.'] unknown. You can create the translation file ['.$file.'] and send it to the webmaster of html2pdf in order to integrate it into a future release'); + } + + // load the file + self::$_list = array(); + $handle = fopen($file, 'r'); + while (!feof($handle)) { + $line = fgetcsv($handle); + if (count($line)!=2) continue; + self::$_list[trim($line[0])] = trim($line[1]); + } + fclose($handle); + } + + /** + * clean the locale + * + * @access public static + */ + static public function clean() + { + self::$_code = null; + self::$_list = array(); + } + + /** + * get a text + * + * @access public static + * @param string $key + * @return string + */ + static public function get($key, $default='######') + { + return (isset(self::$_list[$key]) ? self::$_list[$key] : $default); + } +} \ No newline at end of file diff --git a/boffice/_class/myPdf.class.php b/boffice/_class/myPdf.class.php new file mode 100644 index 0000000..fbe511b --- /dev/null +++ b/boffice/_class/myPdf.class.php @@ -0,0 +1,1415 @@ + PDF convertor + * distributed under the LGPL License + * + * @author Laurent MINGUET + * @version 4.03 + */ + +require_once(dirname(__FILE__).'/tcpdfConfig.php'); +require_once(dirname(__FILE__).'/../_tcpdf_'.HTML2PDF_USED_TCPDF_VERSION.'/tcpdf.php'); + +class HTML2PDF_myPdf extends TCPDF +{ + protected $_footerParam = array(); + protected $_transf = array(); + protected $_myLastPageGroup = null; + protected $_myLastPageGroupNb = 0; + + // used to make a radius with bezier : (4/3 * (sqrt(2) - 1)) + const MY_ARC = 0.5522847498; + + // nb of segment to build a arc with bezier curv + const ARC_NB_SEGMENT = 8; + + /** + * class constructor + * + * @param string $orientation page orientation, same as TCPDF + * @param string $unit User measure unit, same as TCPDF + * @param mixed $format The format used for pages, same as TCPDF + * @param boolean $unicode TRUE means that the input text is unicode (default = true) + * @param String $encoding charset encoding; default is UTF-8 + * @param boolean $diskcache if TRUE reduce the RAM memory usage by caching temporary data on filesystem (slower). + * @access public + */ + public function __construct( + $orientation='P', + $unit='mm', + $format='A4', + $unicode=true, + $encoding='UTF-8', + $diskcache=false) + { + // call the parent constructor + parent::__construct($orientation, $unit, $format, $unicode, $encoding, $diskcache); + + // init the specific parameters used by HTML2PDF + $this->SetCreator(PDF_CREATOR); + $this->SetAutoPageBreak(false, 0); + $this->linestyleCap = '2 J'; + $this->setPrintHeader(false); + $this->jpeg_quality = 90; + + // prepare the automatic footer + $this->SetMyFooter(); + + $this->cMargin = 0; + } + + /** + * Set the parameters for the automatic footer + * + * @param boolean $page display the page number + * @param boolean $date display the date + * @param boolean $hour display the hour + * @param boolean $form display a warning abour forms + * @access public + */ + public function SetMyFooter($page = false, $date = false, $hour = false, $form = false) + { + $page = ($page ? true : false); + $date = ($date ? true : false); + $hour = ($hour ? true : false); + $form = ($form ? true : false); + + $this->_footerParam = array('page' => $page, 'date' => $date, 'hour' => $hour, 'form' => $form); + } + + /** + * This function is call automatically by TCPDF at the end of a page + * It takes no parameters + * + * @access public + */ + public function Footer() + { + // prepare the text from the tranlated text + $txt = ''; + if ($this->_footerParam['form']) { + $txt = (HTML2PDF_locale::get('pdf05')); + } + if ($this->_footerParam['date'] && $this->_footerParam['hour']) { + $txt.= ($txt ? ' - ' : '').(HTML2PDF_locale::get('pdf03')); + } + if ($this->_footerParam['date'] && !$this->_footerParam['hour']) { + $txt.= ($txt ? ' - ' : '').(HTML2PDF_locale::get('pdf01')); + } + if (!$this->_footerParam['date'] && $this->_footerParam['hour']) { + $txt.= ($txt ? ' - ' : '').(HTML2PDF_locale::get('pdf02')); + } + if ($this->_footerParam['page']) { + $txt.= ($txt ? ' - ' : '').(HTML2PDF_locale::get('pdf04')); + } + + if (strlen($txt)>0) { + // replace some values + $toReplace = array( + '[[date_d]]' => date('d'), + '[[date_m]]' => date('m'), + '[[date_y]]' => date('Y'), + '[[date_h]]' => date('H'), + '[[date_i]]' => date('i'), + '[[date_s]]' => date('s'), + '[[page_cu]]' => $this->getMyNumPage(), + '[[page_nb]]' => $this->getMyAliasNbPages(), + ); + $txt = str_replace(array_keys($toReplace), array_values($toReplace), $txt); + + // draw the footer + parent::SetY(-11); + $this->SetFont('helvetica', 'I', 8); + $this->Cell(0, 10, $txt, 0, 0, 'R'); + } + } + + /** + * after cloning a object, we does not want to clone all the front informations + * because it take a lot a time and a lot of memory => we use reference + * + * @param &HTML2PDF_myPdf object + * @access public + */ + public function cloneFontFrom(&$pdf) + { + $this->fonts = &$pdf->getFonts(); + $this->FontFiles = &$pdf->getFontFiles(); + $this->diffs = &$pdf->getDiffs(); + $this->fontlist = &$pdf->getFontList(); + $this->numfonts = &$pdf->getNumFonts(); + $this->fontkeys = &$pdf->getFontKeys(); + $this->font_obj_ids = &$pdf->getFontObjIds(); + $this->annotation_fonts = &$pdf->getAnnotFonts(); + } + + /** + * multiple public accessor for some private attributs + * used only by cloneFontFrom + * + * @return &array + * @access public + */ + public function &getFonts() + { + return $this->fonts; + } + public function &getFontFiles() + { + return $this->FontFiles; + } + public function &getDiffs() + { + return $this->diffs; + } + public function &getFontList() + { + return $this->fontlist; + } + public function &getNumFonts() + { + return $this->numfonts; + } + public function &getFontKeys() + { + return $this->fontkeys; + } + public function &getFontObjIds() + { + return $this->font_obj_ids; + } + public function &getAnnotFonts() + { + return $this->annotation_fonts; + } + + /** + * Verify that a Font is already loaded + * + * @param string Font Key + * @return boolean + * @access public + */ + public function isLoadedFont($fontKey) + { + if (isset($this->fonts[$fontKey])) { + return true; + } + + if (isset($this->CoreFonts[$fontKey])) { + return true; + } + + return false; + } + + /** + * Get the Word Spacing + * + * @access public + * @return float word spacing + */ + public function getWordSpacing() + { + return $this->ws; + } + + /** + * set the Word Spacing + * + * @param float word spacing + * @access public + */ + public function setWordSpacing($ws=0.) + { + $this->ws = $ws; + $this->_out(sprintf('%.3F Tw', $ws*$this->k)); + } + + /** + * start to use a rectangular Cliping Path with radius corners + * + * @param float $x (top left corner) + * @param float $y (top left corner) + * @param float $w (x+w = botom rigth corner) + * @param float $h (y+h = botom rigth corner) + * @param array $cornerTL radius of the Top Left corner + * @param array $cornerTR radius of the Top Right corner + * @param array $cornerBL radius of the Bottom Left corner + * @param array $cornerBR radius of the Bottom Right corner + * @access public + */ + public function clippingPathStart( + $x = null, + $y = null, + $w = null, + $h = null, + $cornerTL=null, + $cornerTR=null, + $cornerBL=null, + $cornerBR=null) + { + // init the path + $path = ''; + + // if we have the position and the size of the rectangle, we can proceed + if ($x!==null && $y!==null && $w!==null && $h!==null) { + // the positions of the rectangle's corners + $x1 = $x*$this->k; + $y1 = ($this->h-$y)*$this->k; + + $x2 = ($x+$w)*$this->k; + $y2 = ($this->h-$y)*$this->k; + + $x3 = ($x+$w)*$this->k; + $y3 = ($this->h-$y-$h)*$this->k; + + $x4 = $x*$this->k; + $y4 = ($this->h-$y-$h)*$this->k; + + // if we have at least one radius corner, then we proceed to a specific path, else it is just a rectangle + if ($cornerTL || $cornerTR || $cornerBL || $cornerBR) { + // prepare the radius values + if ($cornerTL) { + $cornerTL[0] = $cornerTL[0]*$this->k; + $cornerTL[1] =-$cornerTL[1]*$this->k; + } + if ($cornerTR) { + $cornerTR[0] = $cornerTR[0]*$this->k; + $cornerTR[1] =-$cornerTR[1]*$this->k; + } + if ($cornerBL) { + $cornerBL[0] = $cornerBL[0]*$this->k; + $cornerBL[1] =-$cornerBL[1]*$this->k; + } + if ($cornerBR) { + $cornerBR[0] = $cornerBR[0]*$this->k; + $cornerBR[1] =-$cornerBR[1]*$this->k; + } + + // if TL radius then specific start else (X1,Y1) + if ($cornerTL) { + $path.= sprintf('%.2F %.2F m ', $x1+$cornerTL[0], $y1); + } else { + $path.= sprintf('%.2F %.2F m ', $x1, $y1); + } + + // if TR radius then line + arc, else line to (X2,Y2) + if ($cornerTR) { + $xt1 = ($x2-$cornerTR[0])+$cornerTR[0]*self::MY_ARC; + $yt1 = ($y2+$cornerTR[1])-$cornerTR[1]; + $xt2 = ($x2-$cornerTR[0])+$cornerTR[0]; + $yt2 = ($y2+$cornerTR[1])-$cornerTR[1]*self::MY_ARC; + + $path.= sprintf('%.2F %.2F l ', $x2-$cornerTR[0], $y2); + $path.= sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ', $xt1, $yt1, $xt2, $yt2, $x2, $y2+$cornerTR[1]); + } else { + $path.= sprintf('%.2F %.2F l ', $x2, $y2); + } + + // if BR radius then line + arc, else line to (X3, Y3) + if ($cornerBR) { + $xt1 = ($x3-$cornerBR[0])+$cornerBR[0]; + $yt1 = ($y3-$cornerBR[1])+$cornerBR[1]*self::MY_ARC; + $xt2 = ($x3-$cornerBR[0])+$cornerBR[0]*self::MY_ARC; + $yt2 = ($y3-$cornerBR[1])+$cornerBR[1]; + + $path.= sprintf('%.2F %.2F l ', $x3, $y3-$cornerBR[1]); + $path.= sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ', $xt1, $yt1, $xt2, $yt2, $x3-$cornerBR[0], $y3); + } else { + $path.= sprintf('%.2F %.2F l ', $x3, $y3); + } + + // if BL radius then line + arc, else line to (X4, Y4) + if ($cornerBL) { + $xt1 = ($x4+$cornerBL[0])-$cornerBL[0]*self::MY_ARC; + $yt1 = ($y4-$cornerBL[1])+$cornerBL[1]; + $xt2 = ($x4+$cornerBL[0])-$cornerBL[0]; + $yt2 = ($y4-$cornerBL[1])+$cornerBL[1]*self::MY_ARC; + + $path.= sprintf('%.2F %.2F l ', $x4+$cornerBL[0], $y4); + $path.= sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ', $xt1, $yt1, $xt2, $yt2, $x4, $y4-$cornerBL[1]); + } else { + $path.= sprintf('%.2F %.2F l ', $x4, $y4); + } + + // if RL radius then line + arc + if ($cornerTL) { + $xt1 = ($x1+$cornerTL[0])-$cornerTL[0]; + $yt1 = ($y1+$cornerTL[1])-$cornerTL[1]*self::MY_ARC; + $xt2 = ($x1+$cornerTL[0])-$cornerTL[0]*self::MY_ARC; + $yt2 = ($y1+$cornerTL[1])-$cornerTL[1]; + + $path.= sprintf('%.2F %.2F l ', $x1, $y1+$cornerTL[1]); + $path.= sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ', $xt1, $yt1, $xt2, $yt2, $x1+$cornerTL[0], $y1); + } + } else { + $path.= sprintf('%.2F %.2F m ', $x1, $y1); + $path.= sprintf('%.2F %.2F l ', $x2, $y2); + $path.= sprintf('%.2F %.2F l ', $x3, $y3); + $path.= sprintf('%.2F %.2F l ', $x4, $y4); + } + + // close the path + $path.= ' h W n'; + } + + // using the path as a clipping path + $this->_out('q '.$path.' '); + } + + /** + * stop to use the Cliping Path + * + * @access public + */ + public function clippingPathStop() + { + $this->_out(' Q'); + } + + /** + * draw a filled corner of a border with a external and a internal radius + * /--------+ ext2 + * / | + * / /-------+ int2 + * / / + * | / + * | | + * | | + * ext1 +-+ int1 + cen + * + * @param float $ext1X + * @param float $ext1Y + * @param float $ext2X + * @param float $ext2Y + * @param float $int1X + * @param float $int1Y + * @param float $int2X + * @param float $int2Y + * @param float $cenX + * @param float $cenY + * @access public + */ + public function drawCurve($ext1X, $ext1Y, $ext2X, $ext2Y, $int1X, $int1Y, $int2X, $int2Y, $cenX, $cenY) + { + // prepare the coordinates + $ext1X = $ext1X*$this->k; + $ext2X = $ext2X*$this->k; + $int1X = $int1X*$this->k; + $int2X = $int2X*$this->k; + $cenX = $cenX*$this->k; + + $ext1Y = ($this->h-$ext1Y)*$this->k; + $ext2Y = ($this->h-$ext2Y)*$this->k; + $int1Y = ($this->h-$int1Y)*$this->k; + $int2Y = ($this->h-$int2Y)*$this->k; + $cenY = ($this->h-$cenY) *$this->k; + + // init the curve + $path = ''; + + if ($ext1X-$cenX!=0) { + $xt1 = $cenX+($ext1X-$cenX); + $yt1 = $cenY+($ext2Y-$cenY)*self::MY_ARC; + $xt2 = $cenX+($ext1X-$cenX)*self::MY_ARC; + $yt2 = $cenY+($ext2Y-$cenY); + } else { + $xt1 = $cenX+($ext2X-$cenX)*self::MY_ARC; + $yt1 = $cenY+($ext1Y-$cenY); + $xt2 = $cenX+($ext2X-$cenX); + $yt2 = $cenY+($ext1Y-$cenY)*self::MY_ARC; + } + $path.= sprintf('%.2F %.2F m ', $ext1X, $ext1Y); + $path.= sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ', $xt1, $yt1, $xt2, $yt2, $ext2X, $ext2Y); + + if ($int1X-$cenX!=0) { + $xt1 = $cenX+($int1X-$cenX)*self::MY_ARC; + $yt1 = $cenY+($int2Y-$cenY); + $xt2 = $cenX+($int1X-$cenX); + $yt2 = $cenY+($int2Y-$cenY)*self::MY_ARC; + } else { + $xt1 = $cenX+($int2X-$cenX); + $yt1 = $cenY+($int1Y-$cenY)*self::MY_ARC; + $xt2 = $cenX+($int2X-$cenX)*self::MY_ARC; + $yt2 = $cenY+($int1Y-$cenY); + } + $path.= sprintf('%.2F %.2F l ', $int2X, $int2Y); + $path.= sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ', $xt1, $yt1, $xt2, $yt2, $int1X, $int1Y); + + // draw the curve + $this->_out($path . 'f'); + } + + /** + * draw a filled corner of a border with only a external radius + * /--+ ext2 + * / | + * / | + * / | + * | | + * | | + * | | + * ext1 +-----+ int + cen + * + * @param float $ext1X + * @param float $ext1Y + * @param float $ext2X + * @param float $ext2Y + * @param float $intX + * @param float $intY + * @param float $cenX + * @param float $cenY + * @access public + */ + public function drawCorner($ext1X, $ext1Y, $ext2X, $ext2Y, $intX, $intY, $cenX, $cenY) + { + // prepare the coordinates + $ext1X = $ext1X*$this->k; + $ext2X = $ext2X*$this->k; + $intX = $intX*$this->k; + $cenX = $cenX*$this->k; + + $ext1Y = ($this->h-$ext1Y)*$this->k; + $ext2Y = ($this->h-$ext2Y)*$this->k; + $intY = ($this->h-$intY)*$this->k; + $cenY = ($this->h-$cenY)*$this->k; + + // init the curve + $path = ''; + + if ($ext1X-$cenX!=0) { + $xt1 = $cenX+($ext1X-$cenX); + $yt1 = $cenY+($ext2Y-$cenY)*self::MY_ARC; + $xt2 = $cenX+($ext1X-$cenX)*self::MY_ARC; + $yt2 = $cenY+($ext2Y-$cenY); + } else { + $xt1 = $cenX+($ext2X-$cenX)*self::MY_ARC; + $yt1 = $cenY+($ext1Y-$cenY); + $xt2 = $cenX+($ext2X-$cenX); + $yt2 = $cenY+($ext1Y-$cenY)*self::MY_ARC; + } + $path.= sprintf('%.2F %.2F m ', $ext1X, $ext1Y); + $path.= sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c ', $xt1, $yt1, $xt2, $yt2, $ext2X, $ext2Y); + $path.= sprintf('%.2F %.2F l ', $intX, $intY); + $path.= sprintf('%.2F %.2F l ', $ext1X, $ext1Y); + + // draw the curve + $this->_out($path . 'f'); + } + + /** + * Start a transformation + * + * @access public + */ + public function startTransform() + { + $this->_out('q'); + } + + /** + * Stop a transformation + * + * @access public + */ + public function stopTransform() + { + $this->_out('Q'); + } + + /** + * add a Translate transformation + * + * @param float $Tx + * @param float $Ty + * @access public + */ + public function setTranslate($xT, $yT) + { + // Matrix for Translate + $tm[0]=1; + $tm[1]=0; + $tm[2]=0; + $tm[3]=1; + $tm[4]=$xT*$this->k; + $tm[5]=-$yT*$this->k; + + // apply the Transform Matric + $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); + } + + /** + * add a Rotate transformation + * + * @param float $angle + * @param float $Cx + * @param float $Cy + * @access public + */ + public function setRotation($angle, $xC=null, $yC=null) + { + // if no center, rotate around the current posiition + if($xC === null) $xC=$this->x; + if($yC === null) $yC=$this->y; + + // prepare the coordinate + $yC=($this->h-$yC)*$this->k; + $xC*=$this->k; + + // Matrix for Rotate + $tm[0]=cos(deg2rad($angle)); + $tm[1]=sin(deg2rad($angle)); + $tm[2]=-$tm[1]; + $tm[3]=$tm[0]; + $tm[4]=$xC+$tm[1]*$yC-$tm[0]*$xC; + $tm[5]=$yC-$tm[0]*$yC-$tm[1]*$xC; + + // apply the Transform Matric + $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); + } + + /** + * we redifine the original SetX method, because we don't want the automatic treatment. + * It is HTML2PDF that make the treatment + * + * @param float $x + * @param boolean $rtloff NOT USED + * @access public + */ + public function SetX($x, $rtloff=false) + { + $this->x=$x; + } + + /** + * we redifine the original SetY method, because we don't want the automatic treatment. + * It is HTML2PDF that make the treatment + * + * @param float $y + * @param boolean $resetx Reset the X position + * @param boolean $rtloff NOT USED + * @access public + */ + public function SetY($y, $resetx=true, $rtloff=false) + { + if ($resetx) + $this->x=$this->lMargin; + + $this->y=$y; + } + + /** + * we redifine the original SetXY method, because we don't want the automatic treatment. + * It is HTML2PDF that make the treatment + * + * @param integer $x + * @param integer $y + * @param boolean $rtloff NOT USED + * @access public + */ + public function SetXY($x, $y, $rtloff=false) + { + $this->x=$x; + $this->y=$y; + } + + /** + * multiple public accessor because HTML2PDF need to use TCPDF without being a extend of it + * + * @param mixed + * @return mixed + * @access public + */ + public function getK() + { + return $this->k; + } + public function getW() + { + return $this->w; + } + public function getH() + { + return $this->h; + } + public function getlMargin() + { + return $this->lMargin; + } + public function getrMargin() + { + return $this->rMargin; + } + public function gettMargin() + { + return $this->tMargin; + } + public function getbMargin() + { + return $this->bMargin; + } + public function setbMargin($v) + { + $this->bMargin=$v; + } + + /** + * SVG - Convert a SVG Style in PDF Style + * + * @param array $styles SVG Style + * @return string PDF style + * @access public + */ + public function svgSetStyle($styles) + { + // init the PDF style + $style = ''; + + // Style : fill + if ($styles['fill']) { + $this->setFillColorArray($styles['fill']); + $style.= 'F'; + } + + // Style : stroke + if ($styles['stroke'] && $styles['stroke-width']) { + $this->SetDrawColorArray($styles['stroke']); + $this->SetLineWidth($styles['stroke-width']); + $style.= 'D'; + } + + // Style : opacity + if ($styles['fill-opacity']) { + $this->SetAlpha($styles['fill-opacity']); + } + + return $style; + } + + /** + * SVG - make a Rectangle + * + * @param float $x + * @param float $y + * @param float $w + * @param float $h + * @param string $style PDF Style + * @access public + */ + public function svgRect($x, $y, $w, $h, $style) + { + // prepare the 4 corners + $x1=$x; + $x2=$x+$w; + $x3=$x+$w; + $x4=$x; + + $y1=$y; + $y2=$y; + $y3=$y+$h; + $y4=$y+$h; + + // get the Closing operator from the PDF Style + if($style=='F') $op='f'; + elseif($style=='FD' || $style=='DF') $op='B'; + else $op='S'; + + // drawing + $this->_Point($x1, $y1, true); + $this->_Line($x2, $y2, true); + $this->_Line($x3, $y3, true); + $this->_Line($x4, $y4, true); + $this->_Line($x1, $y1, true); + $this->_out($op); + } + + /** + * SVG - make a Line + * + * @param float $x1 + * @param float $y1 + * @param float $x2 + * @param float $y2 + * @access public + */ + public function svgLine($x1, $y1, $x2, $y2) + { + // get the Closing operator + $op='S'; + + // drawing + $this->_Point($x1, $y1, true); + $this->_Line($x2, $y2, true); + $this->_out($op); + } + + /** + * SVG - make a Ellipse + * + * @param float $x0 x Center + * @param float $y0 y Center + * @param float $rx x radius + * @param float $ry y radius + * @param string $style PDF Style + * @access public + */ + public function svgEllipse($x0, $y0, $rx, $ry, $style) + { + // get the Closing operator from the PDF Style + if($style=='F') $op='f'; + elseif($style=='FD' || $style=='DF') $op='B'; + else $op='S'; + + // drawing + $this->_Arc($x0, $y0, $rx, $ry, 0, 2*M_PI, true, true, true); + $this->_out($op); + } + + /** + * SVG - make a Advanced Polygone + * + * @param array $actions list of actions + * @param string $style PDF Style + * @access public + */ + public function svgPolygone($actions, $style) + { + // get the Closing operator from the PDF Style + if($style=='F') $op='f'; + elseif($style=='FD' || $style=='DF') $op='B'; + else $op='S'; + + // To save the First action and the last point + $first = array('', 0, 0); + $last = array(0, 0, 0, 0); + + foreach ($actions as $action) { + switch($action[0]) + { + // Start the Path + case 'M': + case 'm': + $first = $action; + $x = $action[1]; $y = $action[2]; $xc = $x; $yc = $y; + $this->_Point($x, $y, true); + break; + + // Close the Path + case 'Z': + case 'z': + $x = $first[1]; $y = $first[2]; $xc = $x; $yc = $y; + $this->_Line($x, $y, true); + break; + + // Make a Line (new point) + case 'L': + $x = $action[1]; $y = $action[2]; $xc = $x; $yc = $y; + $this->_Line($x, $y, true); + break; + + // Make a Line (vector from last point) + case 'l': + $x = $last[0]+$action[1]; $y = $last[1]+$action[2]; $xc = $x; $yc = $y; + $this->_Line($x, $y, true); + break; + + // Make a Horizontal Line (new point) + case 'H': + $x = $action[1]; $y = $last[1]; $xc = $x; $yc = $y; + $this->_Line($x, $y, true); + break; + + // Make a Horisontal Line (vector from last point) + case 'h': + $x = $last[0]+$action[1]; $y = $last[1]; $xc = $x; $yc = $y; + $this->_Line($x, $y, true); + break; + + // Make a Vertical Line (new point) + case 'V': + $x = $last[0]; $y = $action[1]; $xc = $x; $yc = $y; + $this->_Line($x, $y, true); + break; + + // Make a Vertical Line (vector from last point) + case 'v': + $x = $last[0]; $y = $last[1]+$action[1]; $xc = $x; $yc = $y; + $this->_Line($x, $y, true); + break; + + // Make a Arc (new point) + case 'A': + $rx = $action[1]; // rx + $ry = $action[2]; // ry + $a = $action[3]; // deviation angle of the axis X + $l = $action[4]; // large-arc-flag + $s = $action[5]; // sweep-flag + $x1 = $last[0]; // begin x + $y1 = $last[1]; // begin y + $x2 = $action[6]; // final x + $y2 = $action[7]; // final y + + $this->_Arc2($x1, $y1, $x2, $y2, $rx, $ry, $a, $l, $s, true); + $x = $x2; $y = $y2; $xc = $x; $yc = $y; + break; + + // Make a Arc (vector from last point) + case 'a': + $rx = $action[1]; // rx + $ry = $action[2]; // ry + $a = $action[3]; // deviation angle of the axis X + $l = $action[4]; // large-arc-flag + $s = $action[5]; // sweep-flag + $x1 = $last[0]; // begin x + $y1 = $last[1]; // begin y + $x2 = $last[0]+$action[6]; // final x + $y2 = $last[1]+$action[7]; // final y + + $this->_Arc2($x1, $y1, $x2, $y2, $rx, $ry, $a, $l, $s, true); + $x = $x2; $y = $y2; $xc = $x; $yc = $y; + break; + + // Make a Bezier Curve (new point) + case 'C': + $x1 = $action[1]; + $y1 = $action[2]; + $x2 = $action[3]; + $y2 = $action[4]; + $xf = $action[5]; + $yf = $action[6]; + $this->_Curve($x1, $y1, $x2, $y2, $xf, $yf, true); + $x = $xf; $y = $yf; $xc = $x2; $yc = $y2; + break; + + // Make a Bezier Curve (vector from last point) + case 'c': + $x1 = $last[0]+$action[1]; + $y1 = $last[1]+$action[2]; + $x2 = $last[0]+$action[3]; + $y2 = $last[1]+$action[4]; + $xf = $last[0]+$action[5]; + $yf = $last[1]+$action[6]; + $this->_Curve($x1, $y1, $x2, $y2, $xf, $yf, true); + $x = $xf; $y = $yf; $xc = $x2; $yc = $y2; + break; + + // Unknown Path + default: + throw new HTML2PDF_exception(0, 'SVG Path Error : ['.$action[0].'] unkown'); + } + + // save the last point + $last = array($x, $y, $xc, $yc); + } + + // finish the path + $this->_out($op); + } + + /** + * SVG - go to a point + * + * @param float $x + * @param float $y + * @param boolean $trans apply transformation + * @access protected + */ + protected function _Point($x, $y, $trans = false) + { + if ($trans) $this->ptTransform($x, $y); + + $this->_out(sprintf('%.2F %.2F m', $x, $y)); + } + + /** + * SVG - make a line from the last point to (x,y) + * + * @param float $x + * @param float $y + * @param boolean $trans apply transformation + * @access protected + */ + protected function _Line($x, $y, $trans = false) + { + if ($trans) $this->ptTransform($x, $y); + + $this->_out(sprintf('%.2F %.2F l', $x, $y)); + } + + /** + * SVG - make a bezier curve from the last point to (xf,yf), with the 2 direction points (x1,y1) and (x2,y2) + * + * @param float $x1 + * @param float $y1 + * @param float $x2 + * @param float $y2 + * @param float $xf + * @param float $yf + * @param boolean $trans apply transformation + * @access protected + */ + protected function _Curve($x1, $y1, $x2, $y2, $xf, $yf, $trans = false) + { + if ($trans) { + $this->ptTransform($x1, $y1); + $this->ptTransform($x2, $y2); + $this->ptTransform($xf, $yf); + } + $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c', $x1, $y1, $x2, $y2, $xf, $yf)); + } + + /** + * SVG - make a arc with Center, Radius, from angleBegin to angleEnd + * + * @param float $xc + * @param float $yc + * @param float $rx + * @param float $ry + * @param float $angleBegin in radians + * @param float $angleEng in radians + * @param boolean $direction + * @param boolean $drawFirst, true => add the first point + * @param boolean $trans apply transformation + * @access protected + */ + protected function _Arc( + $xc, + $yc, + $rx, + $ry, + $angleBegin, + $angleEnd, + $direction = true, + $drawFirst = true, + $trans=false) + { + // if we want the no trigo direction : add 2PI to the begin angle, to invert the direction + if (!$direction) $angleBegin+= M_PI*2.; + + // cut in segment to convert in berize curv + $dt = ($angleEnd - $angleBegin)/self::ARC_NB_SEGMENT; + $dtm = $dt/3; + + // center of the arc + $x0 = $xc; $y0 = $yc; + + // calculing the first point + $t1 = $angleBegin; + $a0 = $x0 + ($rx * cos($t1)); + $b0 = $y0 + ($ry * sin($t1)); + $c0 = -$rx * sin($t1); + $d0 = $ry * cos($t1); + + // if drawFirst => draw the first point + if ($drawFirst) $this->_Point($a0, $b0, $trans); + + // foreach segment + for ($i = 1; $i <= self::ARC_NB_SEGMENT; $i++) { + // calculing the next point + $t1 = ($i * $dt)+$angleBegin; + $a1 = $x0 + ($rx * cos($t1)); + $b1 = $y0 + ($ry * sin($t1)); + $c1 = -$rx * sin($t1); + $d1 = $ry * cos($t1); + + // make the bezier curv + $this->_Curve( + $a0 + ($c0 * $dtm), $b0 + ($d0 * $dtm), + $a1 - ($c1 * $dtm), $b1 - ($d1 * $dtm), + $a1, $b1, + $trans + ); + + // save the point + $a0 = $a1; + $b0 = $b1; + $c0 = $c1; + $d0 = $d1; + } + } + + /** + * SVG - make a arc from Pt1 to Pt2, with Radius + * + * @param float $x1 + * @param float $y1 + * @param float $x2 + * @param float $y2 + * @param float $rx + * @param float $ry + * @param float $angle deviation angle of the axis X + * @param boolean $l large-arc-flag + * @param boolean $s sweep-flag + * @param boolean $trans apply transformation + * @access protected + */ + protected function _Arc2($x1, $y1, $x2, $y2, $rx, $ry, $angle=0., $l=0, $s=0, $trans = false) + { + // array to stock the parameters + $v = array(); + + // the original values + $v['x1'] = $x1; + $v['y1'] = $y1; + $v['x2'] = $x2; + $v['y2'] = $y2; + $v['rx'] = $rx; + $v['ry'] = $ry; + + // rotate with the deviation angle of the axis X + $v['xr1'] = $v['x1']*cos($angle) - $v['y1']*sin($angle); + $v['yr1'] = $v['x1']*sin($angle) + $v['y1']*cos($angle); + $v['xr2'] = $v['x2']*cos($angle) - $v['y2']*sin($angle); + $v['yr2'] = $v['x2']*sin($angle) + $v['y2']*cos($angle); + + // the normalized vector + $v['Xr1'] = $v['xr1']/$v['rx']; + $v['Yr1'] = $v['yr1']/$v['ry']; + $v['Xr2'] = $v['xr2']/$v['rx']; + $v['Yr2'] = $v['yr2']/$v['ry']; + $v['dXr'] = $v['Xr2']-$v['Xr1']; + $v['dYr'] = $v['Yr2']-$v['Yr1']; + $v['D'] = $v['dXr']*$v['dXr'] + $v['dYr']*$v['dYr']; + + // if |vector| is Null, or if |vector| > 2 : impossible to make a arc => Line + if ($v['D']==0 || $v['D']>4) { + $this->_Line($x2, $y2, $trans); + return false; + } + + // convert paramters for make a arc with Center, Radius, from angleBegin to angleEnd + $v['s1'] = array(); + $v['s1']['t'] = sqrt((4.-$v['D'])/$v['D']); + $v['s1']['Xr'] = ($v['Xr1']+$v['Xr2'])/2. + $v['s1']['t']*($v['Yr2']-$v['Yr1'])/2.; + $v['s1']['Yr'] = ($v['Yr1']+$v['Yr2'])/2. + $v['s1']['t']*($v['Xr1']-$v['Xr2'])/2.; + $v['s1']['xr'] = $v['s1']['Xr']*$v['rx']; + $v['s1']['yr'] = $v['s1']['Yr']*$v['ry']; + $v['s1']['x'] = $v['s1']['xr']*cos($angle)+$v['s1']['yr']*sin($angle); + $v['s1']['y'] =-$v['s1']['xr']*sin($angle)+$v['s1']['yr']*cos($angle); + $v['s1']['a1'] = atan2($v['y1']-$v['s1']['y'], $v['x1']-$v['s1']['x']); + $v['s1']['a2'] = atan2($v['y2']-$v['s1']['y'], $v['x2']-$v['s1']['x']); + if ($v['s1']['a1']>$v['s1']['a2']) $v['s1']['a1']-=2*M_PI; + + $v['s2'] = array(); + $v['s2']['t'] = -$v['s1']['t']; + $v['s2']['Xr'] = ($v['Xr1']+$v['Xr2'])/2. + $v['s2']['t']*($v['Yr2']-$v['Yr1'])/2.; + $v['s2']['Yr'] = ($v['Yr1']+$v['Yr2'])/2. + $v['s2']['t']*($v['Xr1']-$v['Xr2'])/2.; + $v['s2']['xr'] = $v['s2']['Xr']*$v['rx']; + $v['s2']['yr'] = $v['s2']['Yr']*$v['ry']; + $v['s2']['x'] = $v['s2']['xr']*cos($angle)+$v['s2']['yr']*sin($angle); + $v['s2']['y'] =-$v['s2']['xr']*sin($angle)+$v['s2']['yr']*cos($angle); + $v['s2']['a1'] = atan2($v['y1']-$v['s2']['y'], $v['x1']-$v['s2']['x']); + $v['s2']['a2'] = atan2($v['y2']-$v['s2']['y'], $v['x2']-$v['s2']['x']); + if ($v['s2']['a1']>$v['s2']['a2']) $v['s2']['a1']-=2*M_PI; + + if (!$l) { + if ($s) { + $xc = $v['s2']['x']; + $yc = $v['s2']['y']; + $a1 = $v['s2']['a1']; + $a2 = $v['s2']['a2']; + $this->_Arc($xc, $yc, $rx, $ry, $a1, $a2, true, false, $trans); + } else { + $xc = $v['s1']['x']; + $yc = $v['s1']['y']; + $a1 = $v['s1']['a1']; + $a2 = $v['s1']['a2']; + $this->_Arc($xc, $yc, $rx, $ry, $a1, $a2, false, false, $trans); + } + } else { + if ($s) { + $xc = $v['s1']['x']; + $yc = $v['s1']['y']; + $a1 = $v['s1']['a1']; + $a2 = $v['s1']['a2']; + $this->_Arc($xc, $yc, $rx, $ry, $a1, $a2, true, false, $trans); + } else { + $xc = $v['s2']['x']; + $yc = $v['s2']['y']; + $a1 = $v['s2']['a1']; + $a2 = $v['s2']['a2']; + $this->_Arc($xc, $yc, $rx, $ry, $a1, $a2, false, false, $trans); + } + } + } + + /** + * SVG - transform the point (reference) + * + * @param float &$x + * @param float &$y + * @param boolean $trans true => convert into PDF unit + * @return boolean + * @access public + */ + public function ptTransform(&$x, &$y, $trans=true) + { + // load the last Transfomation Matrix + $nb = count($this->_transf); + if ($nb) $m = $this->_transf[$nb-1]; + else $m = array(1,0,0,1,0,0); + + // apply the Transformation Matrix + list($x,$y) = array(($x*$m[0]+$y*$m[2]+$m[4]),($x*$m[1]+$y*$m[3]+$m[5])); + + // if true => convert into PDF unit + if ($trans) { + $x = $x*$this->k; + $y = ($this->h-$y)*$this->k; + } + + return true; + } + + /** + * SVG - add a transformation Matric + * + * @param array $n matrix + * @access public + */ + public function doTransform($n = null) + { + // get the last Transformation Matrix + $nb = count($this->_transf); + if ($nb) $m = $this->_transf[$nb-1]; + else $m = array(1,0,0,1,0,0); + + // if no transform, get the Identity Matrix + if (!$n) $n = array(1,0,0,1,0,0); + + // create the new Transformation Matrix + $this->_transf[] = array( + $m[0]*$n[0]+$m[2]*$n[1], + $m[1]*$n[0]+$m[3]*$n[1], + $m[0]*$n[2]+$m[2]*$n[3], + $m[1]*$n[2]+$m[3]*$n[3], + $m[0]*$n[4]+$m[2]*$n[5]+$m[4], + $m[1]*$n[4]+$m[3]*$n[5]+$m[5] + ); + } + + /** + * SVG - remove a transformation Matric + * + * @access public + */ + public function undoTransform() + { + array_pop($this->_transf); + } + + /** + * Convert a HTML2PDF barcode in a TCPDF barcode + * + * @param string $code code to print + * @param string $type type of barcode (see tcpdf/barcodes.php for supported formats) + * @param int $x x position in user units + * @param int $y y position in user units + * @param int $w width in user units + * @param int $h height in user units + * @param int $labelFontsize of the Test Label. If false : no Label + * @param array $color color of the foreground + * @access public + */ + public function myBarcode($code, $type, $x, $y, $w, $h, $labelFontsize, $color) + { + // the style of the barcode + $style = array( + 'position' => 'S', + 'text' => ($labelFontsize ? true : false), + 'fgcolor' => $color, + 'bgcolor' => false, + ); + + // build the barcode + $this->write1DBarcode($code, $type, $x, $y, $w, $h, '', $style, 'N'); + + // it Label => add the FontSize to the height + if ($labelFontsize) $h+= ($labelFontsize); + + // return the size of the barcode + return array($w, $h); + } + + /** + * create a automatic Index on a page + * + * @param html2pdf $obj parent object + * @param string $titre Title of the Index Page + * @param integer $sizeTitle Font size for hthe Title + * @param integer $sizeBookmark Font size for the bookmarks + * @param boolean $bookmarkTitle Bookmark the Title + * @param boolean $displayPage Display the page number for each bookmark + * @param integer $page draw the automatic Index on a specific Page. if null => add a page at the end + * @param string $fontName FontName to use + * @access public + */ + public function createIndex( + &$obj, + $titre = 'Index', + $sizeTitle = 20, + $sizeBookmark = 15, + $bookmarkTitle = true, + $displayPage = true, + $page = null, + $fontName = 'helvetica') + { + // bookmark the Title if wanted + if ($bookmarkTitle) $this->Bookmark($titre, 0, -1); + + // display the Title with the good Font size + $this->SetFont($fontName, '', $sizeTitle); + $this->Cell(0, 5, $titre, 0, 1, 'C'); + + // set the good Font size for the bookmarks + $this->SetFont($fontName, '', $sizeBookmark); + $this->Ln(10); + + // get the number of bookmarks + $size=sizeof($this->outlines); + + // get the size of the "P. xx" cell + $pageCellSize=$this->GetStringWidth('p. '.$this->outlines[$size-1]['p'])+2; + + // Foreach bookmark + for ($i=0;$i<$size;$i++) { + // if we need a new page => add a new page + if ($this->getY()+$this->FontSize>=($this->h - $this->bMargin)) { + $obj->_INDEX_NewPage($page); + $this->SetFont($fontName, '', $sizeBookmark); + } + + // Offset of the current level + $level=$this->outlines[$i]['l']; + if($level>0) $this->Cell($level*8); + + // Caption (cut to fit on the width page) + $str=$this->outlines[$i]['t']; + $strsize=$this->GetStringWidth($str); + $availableSize=$this->w-$this->lMargin-$this->rMargin-$pageCellSize-($level*8)-4; + while ($strsize>=$availableSize) { + $str=substr($str, 0, -1); + $strsize=$this->GetStringWidth($str); + } + + // if we want to display the page nmber + if ($displayPage) { + // display the Bookmark Caption + $this->Cell($strsize+2, $this->FontSize+2, $str); + + //Filling dots + $w=$this->w-$this->lMargin-$this->rMargin-$pageCellSize-($level*8)-($strsize+2); + $nb=$w/$this->GetStringWidth('.'); + $dots=str_repeat('.', $nb); + $this->Cell($w, $this->FontSize+2, $dots, 0, 0, 'R'); + + //Page number + $this->Cell($pageCellSize, $this->FontSize+2, 'p. '.$this->outlines[$i]['p'], 0, 1, 'R'); + } else { + // display the Bookmark Caption + $this->Cell($strsize+2, $this->FontSize+2, $str, 0, 1); + } + } + } + + /** + * Returns the string alias used for the total number of pages. + * + * @access public + * @return string; + * @see TCPDF::getAliasNbPages(), TCPDF::getPageGroupAlias() + */ + public function getMyAliasNbPages() + { + if ($this->_myLastPageGroupNb==0) { + return $this->getAliasNbPages(); + } else { + $old = $this->currpagegroup; + $this->currpagegroup = '{nb'.$this->_myLastPageGroupNb.'}'; + $new = $this->getPageGroupAlias(); + $this->currpagegroup = $old; + + return $new; + } + } + + /** + * Returns the current page number. + * + * @access public + * @param integer $page + * @return integer; + */ + public function getMyNumPage($page=null) + { + if ($page===null) { + $page = $this->page; + } + + if ($this->_myLastPageGroupNb==0) { + return $page; + } else { + return $page-$this->_myLastPageGroup; + } + } + + /** + * Start a new group of pages + * + * @access public + * @return integer; + * @see tcpdf::startPageGroup + */ + public function myStartPageGroup() + { + $this->_myLastPageGroup = $this->page-1; + $this->_myLastPageGroupNb++; + } + + /** + * get $_myLastPageGroup; + * + * @access public + * @return integer $_myLastPageGroup; + */ + public function getMyLastPageGroup() + { + return $this->_myLastPageGroup; + } + + /** + * set $_myLastPageGroup; + * + * @access public + * @param integer $myLastPageGroup; + */ + public function setMyLastPageGroup($myLastPageGroup) + { + $this->_myLastPageGroup = $myLastPageGroup; + } + + /** + * get $_myLastPageGroupNb; + * + * @access public + * @return integer $_myLastPageGroupNb; + */ + public function getMyLastPageGroupNb() + { + return $this->_myLastPageGroupNb; + } + + /** + * set $_myLastPageGroupNb; + * + * @access public + * @param integer $myLastPageGroupNb; + */ + public function setMyLastPageGroupNb($myLastPageGroupNb) + { + $this->_myLastPageGroupNb = $myLastPageGroupNb; + } +} diff --git a/boffice/_class/parsingCss.class.php b/boffice/_class/parsingCss.class.php new file mode 100644 index 0000000..2583d8f --- /dev/null +++ b/boffice/_class/parsingCss.class.php @@ -0,0 +1,1812 @@ + PDF convertor + * distributed under the LGPL License + * + * @author Laurent MINGUET + * @version 4.03 + */ + +class HTML2PDF_parsingCss +{ + /** + * reference to the pdf object + * @var TCPDF + */ + protected $_pdf = null; + + protected $_htmlColor = array(); // list of the HTML colors + protected $_onlyLeft = false; // flag if we are in a sub html => only "text-align:left" is used + protected $_defaultFont = null; // default font to use if the asked font does not exist + + public $value = array(); // current values + public $css = array(); // css values + public $cssKeys = array(); // css key, for the execution order + public $table = array(); // level history + + /** + * Constructor + * + * @param &HTML2PDF_myPdf reference to the PDF $object + * @access public + */ + public function __construct(&$pdf) + { + $this->_init(); + $this->setPdfParent($pdf); + } + + /** + * Set the HTML2PDF parent object + * + * @param &HTML2PDF reference to the HTML2PDF parent $object + * @access public + */ + public function setPdfParent(&$pdf) + { + $this->_pdf = &$pdf; + } + + /** + * Inform that we want only "test-align:left" because we are in a sub HTML + * + * @access public + */ + public function setOnlyLeft() + { + $this->value['text-align'] = 'left'; + $this->_onlyLeft = true; + } + + /** + * Get the vales of the parent, if exist + * + * @return array CSS values + * @access public + */ + public function getOldValues() + { + return isset($this->table[count($this->table)-1]) ? $this->table[count($this->table)-1] : $this->value; + } + + /** + * define the Default Font to use, if the font does not exist, or if no font asked + * + * @param string default font-family. If null : Arial for no font asked, and error fot ont does not exist + * @return string old default font-family + * @access public + */ + public function setDefaultFont($default = null) + { + $old = $this->_defaultFont; + $this->_defaultFont = $default; + if ($default) $this->value['font-family'] = $default; + return $old; + } + + /** + * Init the object + * + * @access protected + */ + protected function _init() + { + // get the Web Colors from TCPDF + require(K_PATH_MAIN.'htmlcolors.php'); + $this->_htmlColor = $webcolor; + + // init the Style + $this->table = array(); + $this->value = array(); + $this->initStyle(); + + // Init the styles without legacy + $this->resetStyle(); + } + + /** + * Init the CSS Style + * + * @access public + */ + public function initStyle() + { + $this->value['id_tag'] = 'body'; // tag name + $this->value['id_name'] = null; // tag - attribute name + $this->value['id_id'] = null; // tag - attribute id + $this->value['id_class'] = null; // tag - attribute class + $this->value['id_lst'] = array('*'); // tag - list of legacy + $this->value['mini-size'] = 1.; // specific size report for sup, sub + $this->value['mini-decal'] = 0; // specific position report for 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; + } + + /** + * Init the CSS Style without legacy + * + * @param string tag name + * @access public + */ + public function resetStyle($tagName = '') + { + // prepare somme values + $border = $this->readBorder('solid 1px #000000'); + $units = array( + '1px' => $this->convertToMM('1px'), + '5px' => $this->convertToMM('5px'), + ); + + + // prepare the Collapse attribute + $collapse = isset($this->value['border']['collapse']) ? $this->value['border']['collapse'] : false; + if (!in_array($tagName, array('tr', 'td', 'th', 'thead', 'tbody', 'tfoot'))) $collapse = false; + + // set the global css values + $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, + ); + + // specific values for some tags + if (!in_array($tagName, array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) { + $this->value['margin'] = array('t'=>0,'r'=>0,'b'=>0,'l'=>0); + } + + if (in_array($tagName, array('input', 'select', 'textarea'))) { + $this->value['border']['t'] = null; + $this->value['border']['r'] = null; + $this->value['border']['b'] = null; + $this->value['border']['l'] = null; + } + + if ($tagName=='p') { + $this->value['margin']['t'] = null; + $this->value['margin']['b'] = null; + } + if ($tagName=='blockquote') { + $this->value['margin']['t'] = 3; + $this->value['margin']['r'] = 3; + $this->value['margin']['b'] = 3; + $this->value['margin']['l'] = 6; + } + $this->value['margin-auto'] = false; + + if (in_array($tagName, array('blockquote', 'div', 'fieldset'))) { + $this->value['vertical-align'] = 'top'; + } + + if (in_array($tagName, array('fieldset', 'legend'))) { + $this->value['border'] = array( + 't' => $border, + 'r' => $border, + 'b' => $border, + 'l' => $border, + 'radius' => array( + 'tl' => array($units['5px'], $units['5px']), + 'tr' => array($units['5px'], $units['5px']), + 'br' => array($units['5px'], $units['5px']), + 'bl' => array($units['5px'], $units['5px']) + ), + 'collapse' => false, + ); + } + + if (in_array($tagName, array('ul', 'li'))) { + $this->value['list-style-type'] = ''; + $this->value['list-style-image'] = ''; + } + + if (!in_array($tagName, array('tr', 'td'))) { + $this->value['padding'] = array( + 't' => 0, + 'r' => 0, + 'b' => 0, + 'l' => 0 + ); + } else { + $this->value['padding'] = array( + 't' => $units['1px'], + 'r' => $units['1px'], + 'b' => $units['1px'], + 'l' => $units['1px'] + ); + } + + if ($tagName=='hr') { + $this->value['border'] = array( + 't' => $border, + 'r' => $border, + 'b' => $border, + 'l' => $border, + '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; + } + + /** + * Init the PDF Font + * + * @access public + */ + 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' : ''); + + // font style + $style = $b.$i; + + if ($this->_defaultFont) { + 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=''; + + // complete style + $style.= $u.$d.$o; + + // size : mm => pt + $size = $this->value['font-size']; + $size = 72 * $size / 25.4; + + // apply the font + $this->_pdf->SetFont($family, $style, $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); + } + + /** + * add a level in the CSS history + * + * @access public + */ + public function save() + { + array_push($this->table, $this->value); + } + + /** + * remove a level in the CSS history + * + * @access public + */ + public function load() + { + if (count($this->table)) { + $this->value = array_pop($this->table); + } + } + + /** + * restore the Y positiony (used after a span) + * + * @access public + */ + public function restorePosition() + { + if ($this->value['y']==$this->_pdf->getY()) $this->_pdf->setY($this->value['yc'], false); + } + + /** + * set the New position for the current Tag + * + * @access public + */ + public function setPosition() + { + // get the current position + $currentX = $this->_pdf->getX(); + $currentY = $this->_pdf->getY(); + + // save it + $this->value['xc'] = $currentX; + $this->value['yc'] = $currentY; + + 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'] = $currentX + $x; + $this->value['y'] = $currentY + $y; + } else { + $this->value['x'] = $this->_getLastAbsoluteX()+$x; + $this->value['y'] = $this->_getLastAbsoluteY()+$y; + } + } else { + $this->value['x'] = $currentX; + $this->value['y'] = $currentY; + if ($this->value['margin']['l']) $this->value['x']+= $this->value['margin']['l']; + if ($this->value['margin']['t']) $this->value['y']+= $this->value['margin']['t']; + } + + // save the new position + $this->_pdf->setXY($this->value['x'], $this->value['y']); + } + + /** + * Analise the CSS style to convert it into Form style + * + * @access public + * @param array styles + */ + public function getFormStyle() + { + $prop = array(); + + $prop['alignment'] = $this->value['text-align']; + + if (isset($this->value['background']['color']) && is_array($this->value['background']['color'])) { + $prop['fillColor'] = $this->value['background']['color']; + } + + if (isset($this->value['border']['t']['color'])) { + $prop['strokeColor'] = $this->value['border']['t']['color']; + } + + if (isset($this->value['border']['t']['width'])) { + $prop['lineWidth'] = $this->value['border']['t']['width']; + } + + if (isset($this->value['border']['t']['type'])) { + $prop['borderStyle'] = $this->value['border']['t']['type']; + } + + if (!empty($this->value['color'])) { + $prop['textColor'] = $this->value['color']; + } + + if (!empty($this->value['font-size'])) { + $prop['textSize'] = $this->value['font-size']; + } + + return $prop; + } + + /** + * Analise the CSS style to convert it into SVG style + * + * @access public + * @param string tag name + * @param array styles + */ + public function getSvgStyle($tagName, &$param) + { + // prepare + $tagName = strtolower($tagName); + $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; + + // read the class attribute + $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; + } + + // identify the tag, and the direct styles + $this->value['id_tag'] = $tagName; + $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'][] = $tagName; + 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'][] = $tagName.'.'.$v; + } + } + if ($id) { + $this->value['id_lst'][] = '*#'.$id; + $this->value['id_lst'][] = '#'.$id; + $this->value['id_lst'][] = $tagName.'#'.$id; + } + + // CSS style + $styles = $this->_getFromCSS(); + + // adding the style from the tag + $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 the css properties from the HTML parsing + * + * @access public + * @param string $tagName + * @param array $param + * @param array $legacy + */ + public function analyse($tagName, &$param, $legacy = null) + { + // prepare the informations + $tagName = strtolower($tagName); + $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; + + // get the class names to use + $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; + } + + // prepare the values, and the list of css tags to identify + $this->value['id_tag'] = $tagName; + $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'][] = $tagName; + if (count($class)) { + foreach ($class as $v) { + $this->value['id_lst'][] = '*.'.$v; + $this->value['id_lst'][] = '.'.$v; + $this->value['id_lst'][] = $tagName.'.'.$v; + } + } + if ($id) { + $this->value['id_lst'][] = '*#'.$id; + $this->value['id_lst'][] = '#'.$id; + $this->value['id_lst'][] = $tagName.'#'.$id; + } + + // get the css styles from class + $styles = $this->_getFromCSS(); + + // merge with the css styles from tag + $styles = array_merge($styles, $param['style']); + if (isset($param['allwidth']) && !isset($styles['width'])) $styles['width'] = '100%'; + + // reset some styles, depending on the tag name + $this->resetStyle($tagName); + + // add the legacy values + if ($legacy) { + foreach ($legacy as $legacyName => $legacyValue) { + if (is_array($legacyValue)) { + foreach($legacyValue as $legacy2Name => $legacy2Value) + $this->value[$legacyName][$legacy2Name] = $legacy2Value; + } else { + $this->value[$legacyName] = $legacyValue; + } + } + } + + // some flags + $correctWidth = false; + $noWidth = true; + + // read all the css styles + 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 ($tagName=='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)=='%') $correctWidth=true; + $noWidth = 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 $valK => $valV) { + if (!in_array($valV, array('solid', 'dotted', 'dashed'))) { + $val[$valK] = 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 $valK => $valV) { + $val[$valK] = $this->convertToColor($valV, $res); + if (!$res) { + $val[$valK] = 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 $valK => $valV) { + $val[$valK] = $this->convertToMM($valV, 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 ($tagName=='table') $this->value['border']['collapse'] = ($val=='collapse'); + break; + + case 'border-radius': + $val = explode('/', $val); + if (count($val)>2) { + break; + } + $valH = $this->convertToRadius(trim($val[0])); + if (count($valH)<1 || count($valH)>4) { + break; + } + if (!isset($valH[1])) $valH[1] = $valH[0]; + if (!isset($valH[2])) $valH = array($valH[0], $valH[0], $valH[1], $valH[1]); + if (!isset($valH[3])) $valH[3] = $valH[1]; + if (isset($val[1])) { + $valV = $this->convertToRadius(trim($val[1])); + if (count($valV)<1 || count($valV)>4) { + break; + } + if (!isset($valV[1])) $valV[1] = $valV[0]; + if (!isset($valV[2])) $valV = array($valV[0], $valV[0], $valV[1], $valV[1]); + if (!isset($valV[3])) $valV[3] = $valV[1]; + } else { + $valV = $valH; + } + $this->value['border']['radius'] = array( + 'tl' => array($valH[0], $valV[0]), + 'tr' => array($valH[1], $valV[1]), + 'br' => array($valH[2], $valV[2]), + 'bl' => array($valH[3], $valV[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; + + // only for P tag + 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']; + + // force the text align to left, if asked by html2pdf + if ($this->_onlyLeft) $this->value['text-align'] = 'left'; + + // correction on the width (quick box) + if ($noWidth && in_array($tagName, array('div', 'blockquote', 'fieldset')) && $this->value['position']!='absolute') { + $this->value['width'] = $this->getLastWidth(); + $this->value['width']-= $this->value['margin']['l'] + $this->value['margin']['r']; + } else { + if ($correctWidth) { + if (!in_array($tagName, array('table', 'div', 'blockquote', '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($tagName, 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; + } + + /** + * get the height of the current line + * + * @access public + * @return float $height in mm + */ + public function getLineHeight() + { + $val = $this->value['line-height']; + if ($val=='normal') $val = '108%'; + return $this->convertToMM($val, $this->value['font-size']); + } + + /** + * get the width of the parent + * + * @access public + * @param boolean $mode true => adding padding and border + * @return float $width in mm + */ + 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(); + } + + /** + * get the height of the parent + * + * @access public + * @param boolean $mode true => adding padding and border + * @return float $height in mm + */ + 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(); + } + + /** + * get the value of the float property + * + * @access public + * @return $float left/right + */ + public function getFloat() + { + if ($this->value['float']=='left') return 'left'; + if ($this->value['float']=='right') return 'right'; + return null; + } + + /** + * get the last value for a specific key + * + * @access public + * @param string $key + * @return mixed + */ + public function getLastValue($key) + { + $nb = count($this->table); + if ($nb>0) { + return $this->table[$nb-1][$key]; + } else { + return null; + } + } + + /** + * get the last absolute X + * + * @access protected + * @return float $x + */ + 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(); + } + + /** + * get the last absolute Y + * + * @access protected + * @return float $y + */ + 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(); + } + + /** + * get the CSS properties of the current tag + * + * @access protected + * @return array $styles + */ + protected function _getFromCSS() + { + // styles to apply + $styles = array(); + + // list of the selectors to get in the CSS files + $getit = array(); + + // get the list of the selectors of each tags + $lst = array(); + $lst[] = $this->value['id_lst']; + for ($i=count($this->table)-1; $i>=0; $i--) { + $lst[] = $this->table[$i]['id_lst']; + } + + // foreach selectors in the CSS files, verify if it match with the list of selectors + foreach ($this->cssKeys as $key => $num) { + if ($this->_getReccursiveStyle($key, $lst)) { + $getit[$key] = $num; + } + } + + // if we have selectors + if (count($getit)) { + // get them, but in the definition order, because of priority + asort($getit); + foreach ($getit as $key => $val) $styles = array_merge($styles, $this->css[$key]); + } + + return $styles; + } + + /** + * identify if the selector $key match with the list of tag selectors + * + * @access protected + * @param string $key CSS selector to analyse + * @param array $lst list of the selectors of each tags + * @param string $next next step of parsing the selector + * @return boolean + */ + protected function _getReccursiveStyle($key, $lst, $next = null) + { + // if next step + if ($next!==null) { + // we remove this step + if ($next) $key = trim(substr($key, 0, -strlen($next))); + array_shift($lst); + + // if no more step to identify => return false + if (!count($lst)) { + return false; + } + } + + // for each selector of the current step + foreach ($lst[0] as $name) { + // if selector = key => ok + if ($key==$name) { + return true; + } + + // if the end of the key = the selector and the next step is ok => ok + if (substr($key, -strlen(' '.$name))==' '.$name && $this->_getReccursiveStyle($key, $lst, $name)) { + return true; + } + } + + // if we are not in the first step, we analyse the sub steps (the pareng tag of the current tag) + if ($next!==null && $this->_getReccursiveStyle($key, $lst, '')) { + return true; + } + + // no corresponding found + return false; + } + + /** + * Analyse a border + * + * @access public + * @param string $css css border properties + * @return array border properties + */ + public function readBorder($css) + { + // border none + $none = array('type' => 'none', 'width' => 0, 'color' => array(0, 0, 0)); + + // default value + $type = 'solid'; + $width = $this->convertToMM('1pt'); + $color = array(0, 0, 0); + + // clean up the values + $css = explode(' ', $css); + foreach ($css as $k => $v) { + $v = trim($v); + if ($v) $css[$k] = $v; + else unset($css[$k]); + } + $css = array_values($css); + + // read the values + $res = null; + foreach ($css as $value) { + + // if no border => return none + if ($value=='none' || $value=='hidden') { + return $none; + } + + // try to convert the value as a distance + $tmp = $this->convertToMM($value); + + // if the convert is ok => it is a width + if ($tmp!==null) { + $width = $tmp; + // else, it could be the type + } else if (in_array($value, array('solid', 'dotted', 'dashed', 'double'))) { + $type = $value; + // else, it could be the color + } else { + $tmp = $this->convertToColor($value, $res); + if ($res) $color = $tmp; + } + } + + // if no witdh => return none + if (!$width) return $none; + + // return the border properties + return array('type' => $type, 'width' => $width, 'color' => $color); + } + + /** + * duplicate the borders if needed + * + * @access protected + * @param &array $val + */ + protected function _duplicateBorder(&$val) + { + // 1 value => L => RTB + if (count($val)==1) { + $val[1] = $val[0]; + $val[2] = $val[0]; + $val[3] = $val[0]; + // 2 values => L => R & T => B + } else if (count($val)==2) { + $val[2] = $val[0]; + $val[3] = $val[1]; + // 3 values => T => B + } else if (count($val)==3) { + $val[3] = $val[1]; + } + } + + /** + * Analyse a background + * + * @access public + * @param string $css css background properties + * @param &array $value parsed values (by reference, because, ther is a legacy of the parent CSS properties) + */ + public function convertBackground($css, &$value) + { + // is there a image ? + $text = '/url\(([^)]*)\)/isU'; + if (preg_match($text, $css, $match)) { + // get the image + $value['image'] = $this->convertBackgroundImage($match[0]); + + // remove if from the css properties + $css = preg_replace($text, '', $css); + $css = preg_replace('/[\s]+/', ' ', $css); + } + + // protect some spaces + $css = preg_replace('/,[\s]+/', ',', $css); + + // explode the values + $css = explode(' ', $css); + + // background position to parse + $pos = ''; + + // foreach value + foreach ($css as $val) { + // try to parse the value as a color + $ok = false; + $color = $this->convertToColor($val, $ok); + + // if ok => it is a color + if ($ok) { + $value['color'] = $color; + // else if transparent => no coloàr + } else if ($val=='transparent') { + $value['color'] = null; + // else + } else { + // try to parse the value as a repeat + $repeat = $this->convertBackgroundRepeat($val); + + // if ok => it is repeat + if ($repeat) { + $value['repeat'] = $repeat; + // else => it could only be a position + } else { + $pos.= ($pos ? ' ' : '').$val; + } + } + } + + // if we have a position to parse + if ($pos) { + // try to read it + $pos = $this->convertBackgroundPosition($pos, $ok); + if ($ok) $value['position'] = $pos; + } + } + + /** + * parse a background color + * + * @access public + * @param string $css + * @return string $value + */ + public function convertBackgroundColor($css) + { + $res = null; + if ($css=='transparent') return null; + else return $this->convertToColor($css, $res); + } + + /** + * parse a background image + * + * @access public + * @param string $css + * @return string $value + */ + public function convertBackgroundImage($css) + { + if ($css=='none') + return null; + else if (preg_match('/^url\(([^)]*)\)$/isU', $css, $match)) + return $match[1]; + else + return null; + } + + /** + * parse a background position + * + * @access public + * @param string $css + * @param &boolean $res flag if conver is ok or not + * @return array ($x, $y) + */ + public function convertBackgroundPosition($css, &$res) + { + // init the res + $res = false; + + // explode the value + $css = explode(' ', $css); + + // we must have 2 values. if 0 or >2 : error. if 1 => put center for 2 + if (count($css)<2) { + if (!$css[0]) return null; + $css[1] = 'center'; + } + if (count($css)>2) return null; + + // prepare the values + $x = 0; + $y = 0; + $res = true; + + // convert the first value + if ($css[0]=='left') $x = '0%'; + else if ($css[0]=='center') $x = '50%'; + else if ($css[0]=='right') $x = '100%'; + else if ($css[0]=='top') $y = '0%'; + else if ($css[0]=='bottom') $y = '100%'; + else if (preg_match('/^[-]?[0-9\.]+%$/isU', $css[0])) $x = $css[0]; + else if ($this->convertToMM($css[0])) $x = $this->convertToMM($css[0]); + else $res = false; + + // convert the second value + if ($css[1]=='left') $x = '0%'; + else if ($css[1]=='right') $x = '100%'; + else if ($css[1]=='top') $y = '0%'; + else if ($css[1]=='center') $y = '50%'; + else if ($css[1]=='bottom') $y = '100%'; + else if (preg_match('/^[-]?[0-9\.]+%$/isU', $css[1])) $y = $css[1]; + else if ($this->convertToMM($css[1])) $y = $this->convertToMM($css[1]); + else $res = false; + + // return the values + return array($x, $y); + } + + /** + * parse a background repeat + * + * @access public + * @param string $css + * @return string $value + */ + public function convertBackgroundRepeat($css) + { + switch($css) + { + 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; + } + + /** + * convert a distance to mm + * + * @access public + * @param string $css distance to convert + * @param float $old parent distance + * @return float $value + */ + public function convertToMM($css, $old=0.) + { + $css = trim($css); + if (preg_match('/^[0-9\.\-]+$/isU', $css)) $css.= 'px'; + if (preg_match('/^[0-9\.\-]+px$/isU', $css)) $css = 25.4/96. * str_replace('px', '', $css); + else if (preg_match('/^[0-9\.\-]+pt$/isU', $css)) $css = 25.4/72. * str_replace('pt', '', $css); + else if (preg_match('/^[0-9\.\-]+in$/isU', $css)) $css = 25.4 * str_replace('in', '', $css); + else if (preg_match('/^[0-9\.\-]+mm$/isU', $css)) $css = 1.*str_replace('mm', '', $css); + else if (preg_match('/^[0-9\.\-]+%$/isU', $css)) $css = 1.*$old*str_replace('%', '', $css)/100.; + else $css = null; + + return $css; + } + + /** + * convert a css radius + * + * @access public + * @param string $css + * @return float $value + */ + public function convertToRadius($css) + { + // explode the value + $css = explode(' ', $css); + + foreach ($css as $k => $v) { + $v = trim($v); + if ($v) { + $v = $this->convertToMM($v, 0); + if ($v!==null) { + $css[$k] = $v; + } else { + unset($css[$k]); + } + } else { + unset($css[$k]); + } + } + + return array_values($css); + } + + /** + * convert a css color + * + * @access public + * @param string $css + * @param &boolean $res + * @return array (r,g, b) + */ + public function convertToColor($css, &$res) + { + // prepare the value + $css = trim($css); + $res = true; + + // if transparent => return null + if (strtolower($css)=='transparent') return array(null, null, null); + + // HTML color + if (isset($this->_htmlColor[strtolower($css)])) { + $css = $this->_htmlColor[strtolower($css)]; + $r = floatVal(hexdec(substr($css, 0, 2))); + $v = floatVal(hexdec(substr($css, 2, 2))); + $b = floatVal(hexdec(substr($css, 4, 2))); + return array($r, $v, $b); + } + + // like #FFFFFF + if (preg_match('/^#[0-9A-Fa-f]{6}$/isU', $css)) { + $r = floatVal(hexdec(substr($css, 1, 2))); + $v = floatVal(hexdec(substr($css, 3, 2))); + $b = floatVal(hexdec(substr($css, 5, 2))); + return array($r, $v, $b); + } + + // like #FFF + if (preg_match('/^#[0-9A-F]{3}$/isU', $css)) { + $r = floatVal(hexdec(substr($css, 1, 1).substr($css, 1, 1))); + $v = floatVal(hexdec(substr($css, 2, 1).substr($css, 2, 1))); + $b = floatVal(hexdec(substr($css, 3, 1).substr($css, 3, 1))); + return array($r, $v, $b); + } + + // like rgb(100, 100, 100) + if (preg_match('/rgb\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $css, $match)) { + $r = $this->_convertSubColor($match[1]); + $v = $this->_convertSubColor($match[2]); + $b = $this->_convertSubColor($match[3]); + return array($r*255., $v*255., $b*255.); + } + + // like cmyk(100, 100, 100, 100) + if (preg_match('/cmyk\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $css, $match)) { + $c = $this->_convertSubColor($match[1]); + $m = $this->_convertSubColor($match[2]); + $y = $this->_convertSubColor($match[3]); + $k = $this->_convertSubColor($match[4]); + return array($c*100., $m*100., $y*100., $k*100.); + } + + $res = false; + return array(0., 0., 0.); + } + + /** + * color value to convert + * + * @access protected + * @param string $c + * @return float $c 0.->1. + */ + 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; + } + + /** + * read a css content + * + * @access protected + * @param &string $code + */ + protected function _analyseStyle(&$code) + { + // clean the spaces + $code = preg_replace('/[\s]+/', ' ', $code); + + // remove the comments + $code = preg_replace('/\/\*.*?\*\//s', '', $code); + + // split each CSS code "selector { value }" + preg_match_all('/([^{}]+){([^}]*)}/isU', $code, $match); + + // for each CSS code + for ($k=0; $k1) { + $cod = $tmp[0]; unset($tmp[0]); $tmp = implode(':', $tmp); + $css[trim(strtolower($cod))] = trim($tmp); + } + } + + // explode the names + $names = explode(',', $names); + + // save the values for each names + foreach ($names as $name) { + // clean the name + $name = trim($name); + + // if a selector with somethink lige :hover => continue + if (strpos($name, ':')!==false) continue; + + // save the value + if (!isset($this->css[$name])) + $this->css[$name] = $css; + else + $this->css[$name] = array_merge($this->css[$name], $css); + + } + } + + // get he list of the keys + $this->cssKeys = array_flip(array_keys($this->css)); + } + + /** + * Extract the css files from a html code + * + * @access public + * @param string &$html + */ + public function readStyle(&$html) + { + // the CSS content + $style = ' '; + + // extract the link tags, and remove them in the html code + preg_match_all('/]*)>/isU', $html, $match); + $html = preg_replace('/]*>/isU', '', $html); + $html = preg_replace('/<\/link[^>]*>/isU', '', $html); + + // analyse each link tag + foreach ($match[1] as $code) { + $tmp = array(); + + // read the attributes name=value + $prop = '([a-zA-Z0-9_]+)=([^"\'\s>]+)'; + preg_match_all('/'.$prop.'/is', $code, $match); + for ($k=0; $k we keep it + if (isset($tmp['type']) && strtolower($tmp['type'])=='text/css' && isset($tmp['href'])) { + + // get the href + $url = $tmp['href']; + + // get the content of the css file + $content = @file_get_contents($url); + + // if "http://" in the url + if (strpos($url, 'http://')!==false) { + + // get the domain "http://xxx/" + $url = str_replace('http://', '', $url); + $url = explode('/', $url); + $urlMain = 'http://'.$url[0].'/'; + + // get the absolute url of the path + $urlSelf = $url; unset($urlSelf[count($urlSelf)-1]); $urlSelf = 'http://'.implode('/', $urlSelf).'/'; + + // adapt the url in the css content + $content = preg_replace('/url\(([^\\\\][^)]*)\)/isU', 'url('.$urlSelf.'$1)', $content); + $content = preg_replace('/url\((\\\\[^)]*)\)/isU', 'url('.$urlMain.'$1)', $content); + } else { +// @TODO correction on url in absolute on a local css content + // $content = preg_replace('/url\(([^)]*)\)/isU', 'url('.dirname($url).'/$1)', $content); + } + + // add to the CSS content + $style.= $content."\n"; + } + } + + // extract the style tags des tags style, and remove them in the html code + preg_match_all('/ + + + + + + + + + +Type d'intervention + --- Vider la sélection --- +$val) { echo "".$val.""; } ?> + + + +Thème + --- Vider la sélection --- +$val) { echo "".$val.""; } ?> + + + +Lieu + --- Vider la sélection --- +$val) { echo "".$val.""; } ?> + + + +Intervenant + --- Vider la sélection --- +$val) { echo "".$val['nom']." ".$val['prenom'].""; } ?> + + + +Référent + --- Vider la sélection --- +$val) { echo "".$val['nom'].""; } ?> + + + + + + + + + + + + + + + + + + +