File: html2pdf_svg.class.php - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

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: ?>