SVG PATCH * * Add .svg file support to the tag * * @author Bertrand VILLIEN * @version 0.01 */ if (!defined('__CLASS_HTML2PDF__')) die('ERROR : HTML2PDF_SVG require HTML2PDF. Please include HTML2PDF lib before.'); if (!class_exists('simple_html_dom')) throw new HTML2PDF_exception(0, 'ERROR MISSING LIB : simplehtmldom. Please include simple_html_dom.php !'); class HTML2PDF_SVG extends HTML2PDF { /** * display a image (rewrite) * * @access protected * @param string $src * @param boolean $subLi if true=image of a list * @return boolean depending on "isForOneLine" */ protected function _drawImage($src, $subLi=false) { // If its an .SVG calling the patch : if (preg_match('/\.svg$/', $src) === 1) { return $this->_drawImageSVG($src, $subLi); } // Else its a classic image. Calling original method : else { return parent::_drawImage($src, $subLi); } } /** * display an svg image * * @access protected * @param string $src * @param boolean $subLi if true=image of a list * @return boolean depending on "isForOneLine" */ protected function _drawImageSVG($src, $subLi=false) { /**************************************** * SVG PATCH 1/2 ****************************************/ // Check file exist if (!file_exists($src)) { // If image checking is enabled if ($this->_testIsImage) { throw new HTML2PDF_exception(0, 'SVG file does not exist : '.$src); } // else, display a gray rectangle else { $src = null; $infos = array(16, 16); } } // Load SVG file $svg_raw = file_get_contents($src); if (!$svg_raw) { // If image checking is enabled if ($this->_testIsImage) { throw new HTML2PDF_exception(0, 'SVG file cannot be readed : '.$src); } // else, display a gray rectangle else { $src = null; $infos = array(16, 16); } } // Get the size of the SVG $svg_html = new simple_html_dom(); $svg_html->load($svg_raw); $svg_element = $svg_html->find('svg',0); if ($svg_element === null) throw new HTML2PDF_exception(0, 'SVG file cannot be readed (svg tag not found) : '.$src); if (!$svg_element->hasAttribute('width') || !$svg_element->hasAttribute('height')) throw new HTML2PDF_exception(0, 'SVG file error. Missing width and height attribute of svg tag. From : '.$src); $infos = array($svg_element->getAttribute('width'), $svg_element->getAttribute('height')); $svg_html->clear(); /***************************************/ // convert the size of the image in the unit of the PDF $imageWidth = $infos[0]/$this->pdf->getK(); $imageHeight = $infos[1]/$this->pdf->getK(); // calculate the size from the css style if ($this->parsingCss->value['width'] && $this->parsingCss->value['height']) { $w = $this->parsingCss->value['width']; $h = $this->parsingCss->value['height']; } else if ($this->parsingCss->value['width']) { $w = $this->parsingCss->value['width']; $h = $imageHeight*$w/$imageWidth; } else if ($this->parsingCss->value['height']) { $h = $this->parsingCss->value['height']; $w = $imageWidth*$h/$imageHeight; } else { // convert px to pt $w = 72./96.*$imageWidth; $h = 72./96.*$imageHeight; } // are we in a float $float = $this->parsingCss->getFloat(); // if we are in a float, but if something else if on the line => Break Line if ($float && $this->_maxH) { // make the break line (false if we are in "_isForOneLine" mode) if (!$this->_tag_open_BR(array())) { return false; } } // position of the image $x = $this->pdf->getX(); $y = $this->pdf->getY(); // if the image can not be put on the current line => new line if (!$float && ($x + $w>$this->pdf->getW() - $this->pdf->getrMargin()) && $this->_maxH) { if ($this->_isForOneLine) { return false; } // set the new line $hnl = max($this->_maxH, $this->parsingCss->getLineHeight()); $this->_setNewLine($hnl); // get the new position $x = $this->pdf->getX(); $y = $this->pdf->getY(); } // if the image can not be put on the current page if (($y + $h>$this->pdf->getH() - $this->pdf->getbMargin()) && !$this->_isInOverflow) { // new page $this->_setNewPage(); // get the new position $x = $this->pdf->getX(); $y = $this->pdf->getY(); } // correction for display the image of a list $hT = 0.80*$this->parsingCss->value['font-size']; if ($subLi && $h<$hT) { $y+=($hT-$h); } // add the margin top $yc = $y-$this->parsingCss->value['margin']['t']; // get the width and the position of the parent $old = $this->parsingCss->getOldValues(); if ( $old['width']) { $parentWidth = $old['width']; $parentX = $x; } else { $parentWidth = $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin(); $parentX = $this->pdf->getlMargin(); } // if we are in a gloat => adapt the parent position and width if ($float) { list($lx, $rx) = $this->_getMargins($yc); $parentX = $lx; $parentWidth = $rx-$lx; } // calculate the position of the image, if align to the right if ($parentWidth>$w && $float!='left') { if ($float=='right' || $this->parsingCss->value['text-align']=='li_right') $x = $parentX + $parentWidth - $w-$this->parsingCss->value['margin']['r']-$this->parsingCss->value['margin']['l']; } // display the image if (!$this->_subPart && !$this->_isSubPart) { if ($src) { /**************************************** * SVG PATCH 2/2 ****************************************/ $this->pdf->ImageSVG($src, $x, $y, $w, $h, $this->_isInLink, $_align='', $_palign='', $_border=0, $_fitonpage=false); /***************************************/ } else { // rectangle if the image can not be loaded $this->pdf->setFillColorArray(array(240, 220, 220)); $this->pdf->Rect($x, $y, $w, $h, 'F'); } } // apply the margins $x-= $this->parsingCss->value['margin']['l']; $y-= $this->parsingCss->value['margin']['t']; $w+= $this->parsingCss->value['margin']['l'] + $this->parsingCss->value['margin']['r']; $h+= $this->parsingCss->value['margin']['t'] + $this->parsingCss->value['margin']['b']; if ($float=='left') { // save the current max $this->_maxX = max($this->_maxX, $x+$w); $this->_maxY = max($this->_maxY, $y+$h); // add the image to the margins $this->_addMargins($float, $x, $y, $x+$w, $y+$h); // get the new position list($lx, $rx) = $this->_getMargins($yc); $this->pdf->setXY($lx, $yc); } else if ($float=='right') { // save the current max. We don't save the X because it is not the real max of the line $this->_maxY = max($this->_maxY, $y+$h); // add the image to the margins $this->_addMargins($float, $x, $y, $x+$w, $y+$h); // get the new position list($lx, $rx) = $this->_getMargins($yc); $this->pdf->setXY($lx, $yc); } else { // set the new position at the end of the image $this->pdf->setX($x+$w); // save the current max $this->_maxX = max($this->_maxX, $x+$w); $this->_maxY = max($this->_maxY, $y+$h); $this->_maxH = max($this->_maxH, $h); } return true; } } ?>