001: <?php
002:
003: /**
004: * HTML2PDF Librairy : THE <IMG> SVG PATCH
005: *
006: * Add .svg file support to the <img> tag
007: *
008: * @author Bertrand VILLIEN <bertrand@villien.net>
009: * @version 0.01
010: */
011:
012:
013:
014: if (!defined('__CLASS_HTML2PDF__'))
015: die('ERROR : HTML2PDF_SVG require HTML2PDF. Please include HTML2PDF lib before.');
016:
017: if (!class_exists('simple_html_dom'))
018: throw new HTML2PDF_exception(0, 'ERROR MISSING LIB : simplehtmldom. Please include simple_html_dom.php !');
019:
020:
021:
022:
023:
024: class HTML2PDF_SVG extends HTML2PDF {
025:
026:
027: /**
028: * display a image (rewrite)
029: *
030: * @access protected
031: * @param string $src
032: * @param boolean $subLi if true=image of a list
033: * @return boolean depending on "isForOneLine"
034: */
035: protected function _drawImage($src, $subLi=false)
036: {
037: // If its an .SVG calling the patch :
038: if (preg_match('/\.svg$/', $src) === 1) {
039: return $this->_drawImageSVG($src, $subLi);
040: }
041: // Else its a classic image. Calling original method :
042: else {
043: return parent::_drawImage($src, $subLi);
044: }
045: }
046:
047:
048: /**
049: * display an svg image
050: *
051: * @access protected
052: * @param string $src
053: * @param boolean $subLi if true=image of a list
054: * @return boolean depending on "isForOneLine"
055: */
056: protected function _drawImageSVG($src, $subLi=false)
057: {
058:
059:
060: /****************************************
061: * SVG PATCH 1/2
062: ****************************************/
063:
064:
065: // Check file exist
066: if (!file_exists($src)) {
067: // If image checking is enabled
068: if ($this->_testIsImage) {
069: throw new HTML2PDF_exception(0, 'SVG file does not exist : '.$src);
070: }
071: // else, display a gray rectangle
072: else {
073: $src = null;
074: $infos = array(16, 16);
075: }
076: }
077:
078: // Load SVG file
079: $svg_raw = file_get_contents($src);
080: if (!$svg_raw) {
081: // If image checking is enabled
082: if ($this->_testIsImage) {
083: throw new HTML2PDF_exception(0, 'SVG file cannot be readed : '.$src);
084: }
085: // else, display a gray rectangle
086: else {
087: $src = null;
088: $infos = array(16, 16);
089: }
090: }
091:
092: // Get the size of the SVG
093: $svg_html = new simple_html_dom();
094: $svg_html->load($svg_raw);
095: $svg_element = $svg_html->find('svg',0);
096: if ($svg_element === null)
097: throw new HTML2PDF_exception(0, 'SVG file cannot be readed (svg tag not found) : '.$src);
098: if (!$svg_element->hasAttribute('width') || !$svg_element->hasAttribute('height'))
099: throw new HTML2PDF_exception(0, 'SVG file error. Missing width and height attribute of svg tag. From : '.$src);
100: $infos = array($svg_element->getAttribute('width'), $svg_element->getAttribute('height'));
101: $svg_html->clear();
102:
103:
104: /***************************************/
105:
106:
107:
108:
109: // convert the size of the image in the unit of the PDF
110: $imageWidth = $infos[0]/$this->pdf->getK();
111: $imageHeight = $infos[1]/$this->pdf->getK();
112:
113: // calculate the size from the css style
114: if ($this->parsingCss->value['width'] && $this->parsingCss->value['height']) {
115: $w = $this->parsingCss->value['width'];
116: $h = $this->parsingCss->value['height'];
117: } else if ($this->parsingCss->value['width']) {
118: $w = $this->parsingCss->value['width'];
119: $h = $imageHeight*$w/$imageWidth;
120: } else if ($this->parsingCss->value['height']) {
121: $h = $this->parsingCss->value['height'];
122: $w = $imageWidth*$h/$imageHeight;
123: } else {
124: // convert px to pt
125: $w = 72./96.*$imageWidth;
126: $h = 72./96.*$imageHeight;
127: }
128:
129: // are we in a float
130: $float = $this->parsingCss->getFloat();
131:
132: // if we are in a float, but if something else if on the line => Break Line
133: if ($float && $this->_maxH) {
134: // make the break line (false if we are in "_isForOneLine" mode)
135: if (!$this->_tag_open_BR(array())) {
136: return false;
137: }
138: }
139:
140: // position of the image
141: $x = $this->pdf->getX();
142: $y = $this->pdf->getY();
143:
144: // if the image can not be put on the current line => new line
145: if (!$float && ($x + $w>$this->pdf->getW() - $this->pdf->getrMargin()) && $this->_maxH) {
146: if ($this->_isForOneLine) {
147: return false;
148: }
149:
150: // set the new line
151: $hnl = max($this->_maxH, $this->parsingCss->getLineHeight());
152: $this->_setNewLine($hnl);
153:
154: // get the new position
155: $x = $this->pdf->getX();
156: $y = $this->pdf->getY();
157: }
158:
159: // if the image can not be put on the current page
160: if (($y + $h>$this->pdf->getH() - $this->pdf->getbMargin()) && !$this->_isInOverflow) {
161: // new page
162: $this->_setNewPage();
163:
164: // get the new position
165: $x = $this->pdf->getX();
166: $y = $this->pdf->getY();
167: }
168:
169: // correction for display the image of a list
170: $hT = 0.80*$this->parsingCss->value['font-size'];
171: if ($subLi && $h<$hT) {
172: $y+=($hT-$h);
173: }
174:
175: // add the margin top
176: $yc = $y-$this->parsingCss->value['margin']['t'];
177:
178: // get the width and the position of the parent
179: $old = $this->parsingCss->getOldValues();
180: if ( $old['width']) {
181: $parentWidth = $old['width'];
182: $parentX = $x;
183: } else {
184: $parentWidth = $this->pdf->getW() - $this->pdf->getlMargin() - $this->pdf->getrMargin();
185: $parentX = $this->pdf->getlMargin();
186: }
187:
188: // if we are in a gloat => adapt the parent position and width
189: if ($float) {
190: list($lx, $rx) = $this->_getMargins($yc);
191: $parentX = $lx;
192: $parentWidth = $rx-$lx;
193: }
194:
195: // calculate the position of the image, if align to the right
196: if ($parentWidth>$w && $float!='left') {
197: if ($float=='right' || $this->parsingCss->value['text-align']=='li_right') $x = $parentX + $parentWidth - $w-$this->parsingCss->value['margin']['r']-$this->parsingCss->value['margin']['l'];
198: }
199:
200: // display the image
201: if (!$this->_subPart && !$this->_isSubPart) {
202: if ($src) {
203:
204:
205:
206: /****************************************
207: * SVG PATCH 2/2
208: ****************************************/
209:
210: $this->pdf->ImageSVG($src, $x, $y, $w, $h, $this->_isInLink, $_align='', $_palign='', $_border=0, $_fitonpage=false);
211:
212: /***************************************/
213:
214:
215:
216: } else {
217: // rectangle if the image can not be loaded
218: $this->pdf->setFillColorArray(array(240, 220, 220));
219: $this->pdf->Rect($x, $y, $w, $h, 'F');
220: }
221: }
222:
223: // apply the margins
224: $x-= $this->parsingCss->value['margin']['l'];
225: $y-= $this->parsingCss->value['margin']['t'];
226: $w+= $this->parsingCss->value['margin']['l'] + $this->parsingCss->value['margin']['r'];
227: $h+= $this->parsingCss->value['margin']['t'] + $this->parsingCss->value['margin']['b'];
228:
229: if ($float=='left') {
230: // save the current max
231: $this->_maxX = max($this->_maxX, $x+$w);
232: $this->_maxY = max($this->_maxY, $y+$h);
233:
234: // add the image to the margins
235: $this->_addMargins($float, $x, $y, $x+$w, $y+$h);
236:
237: // get the new position
238: list($lx, $rx) = $this->_getMargins($yc);
239: $this->pdf->setXY($lx, $yc);
240: } else if ($float=='right') {
241: // save the current max. We don't save the X because it is not the real max of the line
242: $this->_maxY = max($this->_maxY, $y+$h);
243:
244: // add the image to the margins
245: $this->_addMargins($float, $x, $y, $x+$w, $y+$h);
246:
247: // get the new position
248: list($lx, $rx) = $this->_getMargins($yc);
249: $this->pdf->setXY($lx, $yc);
250: } else {
251: // set the new position at the end of the image
252: $this->pdf->setX($x+$w);
253:
254: // save the current max
255: $this->_maxX = max($this->_maxX, $x+$w);
256: $this->_maxY = max($this->_maxY, $y+$h);
257: $this->_maxH = max($this->_maxH, $h);
258: }
259:
260: return true;
261: }
262:
263: }
264:
265:
266:
267:
268:
269:
270: ?>