diff options
author | tcit <tcit@tcit.fr> | 2014-09-27 19:34:17 +0200 |
---|---|---|
committer | tcit <tcit@tcit.fr> | 2014-09-27 19:34:17 +0200 |
commit | 824f8c45edb20e27221e92805b0090f1768a2756 (patch) | |
tree | 8563a41cc27619347c851b3a06285bf2474b69dd /inc/3rdparty/libraries/mpdf/classes/svg.php | |
parent | d4690a8fa18c27c6d98c1c76ac1d1d2c35a1ebbb (diff) | |
download | wallabag-824f8c45edb20e27221e92805b0090f1768a2756.tar.gz wallabag-824f8c45edb20e27221e92805b0090f1768a2756.tar.zst wallabag-824f8c45edb20e27221e92805b0090f1768a2756.zip |
changed mpdf with tcpdf
Diffstat (limited to 'inc/3rdparty/libraries/mpdf/classes/svg.php')
-rw-r--r-- | inc/3rdparty/libraries/mpdf/classes/svg.php | 2703 |
1 files changed, 0 insertions, 2703 deletions
diff --git a/inc/3rdparty/libraries/mpdf/classes/svg.php b/inc/3rdparty/libraries/mpdf/classes/svg.php deleted file mode 100644 index 571f4edd..00000000 --- a/inc/3rdparty/libraries/mpdf/classes/svg.php +++ /dev/null | |||
@@ -1,2703 +0,0 @@ | |||
1 | <?php | ||
2 | // svg class modified for mPDF version 4.4.003 by Ian Back: based on - | ||
3 | // svg2pdf fpdf class | ||
4 | // sylvain briand (syb@godisaduck.com), modified by rick trevino (rtrevino1@yahoo.com) | ||
5 | // http://www.godisaduck.com/svg2pdf_with_fpdf | ||
6 | // http://rhodopsin.blogspot.com | ||
7 | // | ||
8 | // cette class etendue est open source, toute modification devra cependant etre repertoriée~ | ||
9 | |||
10 | |||
11 | // NB UNITS - Works in pixels as main units - converting to PDF units when outputing to PDF string | ||
12 | // and on returning size | ||
13 | |||
14 | class SVG { | ||
15 | |||
16 | var $svg_gradient; // array - contient les infos sur les gradient fill du svg classé par id du svg | ||
17 | var $svg_shadinglist; // array - contient les ids des objet shading | ||
18 | var $svg_info; // array contenant les infos du svg voulue par l'utilisateur | ||
19 | var $svg_attribs; // array - holds all attributes of root <svg> tag | ||
20 | var $svg_style; // array contenant les style de groupes du svg | ||
21 | var $svg_string; // String contenant le tracage du svg en lui même. | ||
22 | var $txt_data; // array - holds string info to write txt to image | ||
23 | var $txt_style; // array - current text style | ||
24 | var $mpdf_ref; | ||
25 | var $xbase; // mPDF 4.4.003 | ||
26 | var $ybase; // mPDF 4.4.003 | ||
27 | var $svg_error; // mPDF 4.4.003 | ||
28 | var $subPathInit; // mPDF 4.4.003 | ||
29 | var $spxstart; // mPDF 4.4.003 | ||
30 | var $spystart; // mPDF 4.4.003 | ||
31 | var $kp; // mPDF 4.4.003 convert pixels to PDF units | ||
32 | var $pathBBox; // mPDF 5.0.039 | ||
33 | |||
34 | function SVG(&$mpdf){ | ||
35 | $this->svg_gradient = array(); | ||
36 | $this->svg_shadinglist = array(); | ||
37 | $this->txt_data = array(); | ||
38 | $this->svg_string = ''; | ||
39 | $this->svg_info = array(); | ||
40 | $this->svg_attribs = array(); | ||
41 | $this->xbase = 0; | ||
42 | $this->ybase = 0; | ||
43 | $this->svg_error = false; | ||
44 | $this->subPathInit = false; // mPDF 4.4.003 | ||
45 | $this->dashesUsed = false; // mPDF 5.0 | ||
46 | $this->mpdf_ref =& $mpdf; | ||
47 | |||
48 | $this->kp = 72 / $mpdf->img_dpi; // mPDF 4.4.003 constant To convert pixels to pts/PDF units | ||
49 | $this->kf = 1; // mPDF 5.0.039 constant To convert font size if re-mapped | ||
50 | $this->pathBBox = array(); // mPDF 5.0.039 | ||
51 | |||
52 | $this->svg_style = array( | ||
53 | array( | ||
54 | 'fill' => 'black', // mPDF 4.4.008 | ||
55 | 'fill-opacity' => 1, // remplissage opaque par defaut | ||
56 | 'fill-rule' => 'nonzero', // mode de remplissage par defaut | ||
57 | 'stroke' => 'none', // pas de trait par defaut | ||
58 | 'stroke-linecap' => 'butt', // style de langle par defaut | ||
59 | 'stroke-linejoin' => 'miter', // | ||
60 | 'stroke-miterlimit' => 4, // limite de langle par defaut | ||
61 | 'stroke-opacity' => 1, // trait opaque par defaut | ||
62 | 'stroke-width' => 1, // mPDF 4.4.011 | ||
63 | 'stroke-dasharray' => 0, // mPDF 4.4.003 | ||
64 | 'stroke-dashoffset' => 0, // mPDF 4.4.003 | ||
65 | 'color' => '' // mPDF 4.4.005 | ||
66 | ) | ||
67 | ); | ||
68 | |||
69 | $this->txt_style = array( | ||
70 | array( | ||
71 | 'fill' => 'black', // pas de remplissage par defaut | ||
72 | 'font-family' => $mpdf->default_font, | ||
73 | 'font-size' => $mpdf->default_font_size, // ****** this is pts | ||
74 | 'font-weight' => 'normal', // normal | bold | ||
75 | 'font-style' => 'normal', // italic | normal | ||
76 | 'text-anchor' => 'start', // alignment: start, middle, end | ||
77 | /* mPDF 5.0.041 */ | ||
78 | 'fill-opacity' => 1, // remplissage opaque par defaut | ||
79 | 'fill-rule' => 'nonzero', // mode de remplissage par defaut | ||
80 | 'stroke' => 'none', // pas de trait par defaut | ||
81 | 'stroke-opacity' => 1, // trait opaque par defaut | ||
82 | 'stroke-width' => 1, // mPDF 4.4.011 | ||
83 | 'color' => '' // mPDF 4.4.005 | ||
84 | ) | ||
85 | ); | ||
86 | |||
87 | |||
88 | |||
89 | } | ||
90 | |||
91 | function svgGradient($gradient_info, $attribs, $element){ | ||
92 | $n = count($this->mpdf_ref->gradients)+1; | ||
93 | |||
94 | // Get bounding dimensions of element | ||
95 | $w = 100; | ||
96 | $h = 100; | ||
97 | $x_offset = 0; | ||
98 | $y_offset = 0; | ||
99 | if ($element=='rect') { | ||
100 | $w = $attribs['width']; | ||
101 | $h = $attribs['height']; | ||
102 | $x_offset = $attribs['x']; | ||
103 | $y_offset = $attribs['y']; | ||
104 | } | ||
105 | else if ($element=='ellipse') { | ||
106 | $w = $attribs['rx']*2; | ||
107 | $h = $attribs['ry']*2; | ||
108 | $x_offset = $attribs['cx']-$attribs['rx']; | ||
109 | $y_offset = $attribs['cy']-$attribs['ry']; | ||
110 | } | ||
111 | else if ($element=='circle') { | ||
112 | $w = $attribs['r']*2; | ||
113 | $h = $attribs['r']*2; | ||
114 | $x_offset = $attribs['cx']-$attribs['r']; | ||
115 | $y_offset = $attribs['cy']-$attribs['r']; | ||
116 | } | ||
117 | else if ($element=='polygon') { | ||
118 | $pts = preg_split('/[ ,]+/', trim($attribs['points'])); | ||
119 | $maxr=$maxb=0; | ||
120 | $minl=$mint=999999; | ||
121 | for ($i=0;$i<count($pts); $i++) { | ||
122 | if ($i % 2 == 0) { // x values | ||
123 | $minl = min($minl,$pts[$i]); | ||
124 | $maxr = max($maxr,$pts[$i]); | ||
125 | } | ||
126 | else { // y values | ||
127 | $mint = min($mint,$pts[$i]); | ||
128 | $maxb = max($maxb,$pts[$i]); | ||
129 | } | ||
130 | } | ||
131 | $w = $maxr-$minl; | ||
132 | $h = $maxb-$mint; | ||
133 | $x_offset = $minl; | ||
134 | $y_offset = $mint; | ||
135 | } | ||
136 | else if ($element=='path') { | ||
137 | // mPDF 5.0.039 | ||
138 | if (is_array($this->pathBBox) && $this->pathBBox[2]>0) { | ||
139 | $w = $this->pathBBox[2]; | ||
140 | $h = $this->pathBBox[3]; | ||
141 | $x_offset = $this->pathBBox[0]; | ||
142 | $y_offset = $this->pathBBox[1]; | ||
143 | } | ||
144 | else { | ||
145 | preg_match_all('/([a-z]|[A-Z])([ ,\-.\d]+)*/', $attribs['d'], $commands, PREG_SET_ORDER); | ||
146 | $maxr=$maxb=0; | ||
147 | $minl=$mint=999999; | ||
148 | foreach($commands as $c){ | ||
149 | if(count($c)==3){ | ||
150 | list($tmp, $cmd, $arg) = $c; | ||
151 | if ($cmd=='M' || $cmd=='L' || $cmd=='C' || $cmd=='S' || $cmd=='Q' || $cmd=='T') { | ||
152 | $pts = preg_split('/[ ,]+/', trim($arg)); | ||
153 | for ($i=0;$i<count($pts); $i++) { | ||
154 | if ($i % 2 == 0) { // x values | ||
155 | $minl = min($minl,$pts[$i]); | ||
156 | $maxr = max($maxr,$pts[$i]); | ||
157 | } | ||
158 | else { // y values | ||
159 | $mint = min($mint,$pts[$i]); | ||
160 | $maxb = max($maxb,$pts[$i]); | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | if ($cmd=='H') { // sets new x | ||
165 | $minl = min($minl,$arg); | ||
166 | $maxr = max($maxr,$arg); | ||
167 | } | ||
168 | if ($cmd=='V') { // sets new y | ||
169 | $mint = min($mint,$arg); | ||
170 | $maxb = max($maxb,$arg); | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | $w = $maxr-$minl; | ||
175 | $h = $maxb-$mint; | ||
176 | $x_offset = $minl; | ||
177 | $y_offset = $mint; | ||
178 | } | ||
179 | } | ||
180 | if (!$w || $w==-999999) { $w = 100; } | ||
181 | if (!$h || $h==-999999) { $h = 100; } | ||
182 | if ($x_offset==999999) { $x_offset = 0; } | ||
183 | if ($y_offset==999999) { $y_offset = 0; } | ||
184 | |||
185 | // mPDF 4.5.010 | ||
186 | // TRANSFORMATIONS | ||
187 | $transformations = ''; | ||
188 | if (isset($gradient_info['transform'])){ | ||
189 | preg_match_all('/(matrix|translate|scale|rotate|skewX|skewY)\((.*?)\)/is',$gradient_info['transform'],$m); | ||
190 | if (count($m[0])) { | ||
191 | for($i=0; $i<count($m[0]); $i++) { | ||
192 | $c = strtolower($m[1][$i]); | ||
193 | $v = trim($m[2][$i]); | ||
194 | $vv = preg_split('/[ ,]+/',$v); | ||
195 | if ($c=='matrix' && count($vv)==6) { | ||
196 | // mPDF 5.0.039 | ||
197 | // Note angle of rotation is reversed (from SVG to PDF), so vv[1] and vv[2] are negated | ||
198 | // cf svgDefineStyle() | ||
199 | $transformations .= sprintf(' %.3F %.3F %.3F %.3F %.3F %.3F cm ', $vv[0], -$vv[1], -$vv[2], $vv[3], $vv[4]*$this->kp, -$vv[5]*$this->kp); | ||
200 | } | ||
201 | else if ($c=='translate' && count($vv)) { | ||
202 | $tm[4] = $vv[0]; | ||
203 | if (count($vv)==2) { $t_y = -$vv[1]; } | ||
204 | else { $t_y = 0; } | ||
205 | $tm[5] = $t_y; | ||
206 | $transformations .= sprintf(' 1 0 0 1 %.3F %.3F cm ', $tm[4]*$this->kp, $tm[5]*$this->kp); | ||
207 | } | ||
208 | else if ($c=='scale' && count($vv)) { | ||
209 | if (count($vv)==2) { $s_y = $vv[1]; } | ||
210 | else { $s_y = $vv[0]; } | ||
211 | $tm[0] = $vv[0]; | ||
212 | $tm[3] = $s_y; | ||
213 | $transformations .= sprintf(' %.3F 0 0 %.3F 0 0 cm ', $tm[0], $tm[3]); | ||
214 | } | ||
215 | else if ($c=='rotate' && count($vv)) { | ||
216 | $tm[0] = cos(deg2rad(-$vv[0])); | ||
217 | $tm[1] = sin(deg2rad(-$vv[0])); | ||
218 | $tm[2] = -$tm[1]; | ||
219 | $tm[3] = $tm[0]; | ||
220 | if (count($vv)==3) { | ||
221 | $transformations .= sprintf(' 1 0 0 1 %.3F %.3F cm ', $vv[1]*$this->kp, -$vv[2]*$this->kp); | ||
222 | } | ||
223 | $transformations .= sprintf(' %.3F %.3F %.3F %.3F 0 0 cm ', $tm[0], $tm[1], $tm[2], $tm[3]); | ||
224 | if (count($vv)==3) { | ||
225 | $transformations .= sprintf(' 1 0 0 1 %.3F %.3F cm ', -$vv[1]*$this->kp, $vv[2]*$this->kp); | ||
226 | } | ||
227 | } | ||
228 | else if ($c=='skewx' && count($vv)) { | ||
229 | $tm[2] = tan(deg2rad(-$vv[0])); | ||
230 | $transformations .= sprintf(' 1 0 %.3F 1 0 0 cm ', $tm[2]); | ||
231 | } | ||
232 | else if ($c=='skewy' && count($vv)) { | ||
233 | $tm[1] = tan(deg2rad(-$vv[0])); | ||
234 | $transformations .= sprintf(' 1 %.3F 0 1 0 0 cm ', $tm[1]); | ||
235 | } | ||
236 | |||
237 | } | ||
238 | } | ||
239 | } | ||
240 | |||
241 | |||
242 | $return = ""; | ||
243 | |||
244 | // mPDF 5.0.039 | ||
245 | if (isset($gradient_info['units']) && strtolower($gradient_info['units'])=='userspaceonuse') { | ||
246 | if ($transformations) { $return .= $transformations; } | ||
247 | } | ||
248 | // mPDF 5.0.040 | ||
249 | $spread = 'P'; // pad | ||
250 | if (isset($gradient_info['spread'])) { | ||
251 | if (strtolower($gradient_info['spread'])=='reflect') { $spread = 'F'; } // reflect | ||
252 | else if (strtolower($gradient_info['spread'])=='repeat') { $spread = 'R'; } // repeat | ||
253 | } | ||
254 | |||
255 | |||
256 | for ($i=0; $i<(count($gradient_info['color'])); $i++) { | ||
257 | if (stristr($gradient_info['color'][$i]['offset'], '%')!== false) { $gradient_info['color'][$i]['offset'] = ($gradient_info['color'][$i]['offset']+0)/100; } | ||
258 | if (stristr($gradient_info['color'][($i+1)]['offset'], '%')!== false) { $gradient_info['color'][($i+1)]['offset'] = ($gradient_info['color'][($i+1)]['offset']+0)/100; } | ||
259 | if ($gradient_info['color'][$i]['offset']<0) { $gradient_info['color'][$i]['offset'] = 0; } | ||
260 | if ($gradient_info['color'][$i]['offset']>1) { $gradient_info['color'][$i]['offset'] = 1; } | ||
261 | if ($i>0) { | ||
262 | if ($gradient_info['color'][$i]['offset']<$gradient_info['color'][($i-1)]['offset']) { | ||
263 | $gradient_info['color'][$i]['offset']=$gradient_info['color'][($i-1)]['offset']; | ||
264 | } | ||
265 | } | ||
266 | } | ||
267 | |||
268 | if ($gradient_info['color'][0]['offset']>0) { | ||
269 | array_unshift($gradient_info['color'], $gradient_info['color'][0]); | ||
270 | $gradient_info['color'][0]['offset'] = 0; | ||
271 | } | ||
272 | $ns = count($gradient_info['color']); | ||
273 | if ($gradient_info['color'][($ns-1)]['offset']<1) { | ||
274 | $gradient_info['color'][] = $gradient_info['color'][($ns-1)]; | ||
275 | $gradient_info['color'][($ns)]['offset'] = 1; | ||
276 | } | ||
277 | $ns = count($gradient_info['color']); | ||
278 | |||
279 | |||
280 | |||
281 | |||
282 | if ($gradient_info['type'] == 'linear'){ | ||
283 | // mPDF 4.4.003 | ||
284 | if (isset($gradient_info['units']) && strtolower($gradient_info['units'])=='userspaceonuse') { | ||
285 | if (isset($gradient_info['info']['x1'])) { $gradient_info['info']['x1'] = ($gradient_info['info']['x1']-$x_offset) / $w; } | ||
286 | if (isset($gradient_info['info']['y1'])) { $gradient_info['info']['y1'] = ($gradient_info['info']['y1']-$y_offset) / $h; } | ||
287 | if (isset($gradient_info['info']['x2'])) { $gradient_info['info']['x2'] = ($gradient_info['info']['x2']-$x_offset) / $w; } | ||
288 | if (isset($gradient_info['info']['y2'])) { $gradient_info['info']['y2'] = ($gradient_info['info']['y2']-$y_offset) / $h; } | ||
289 | } | ||
290 | if (isset($gradient_info['info']['x1'])) { $x1 = $gradient_info['info']['x1']; } | ||
291 | else { $x1 = 0; } | ||
292 | if (isset($gradient_info['info']['y1'])) { $y1 = $gradient_info['info']['y1']; } | ||
293 | else { $y1 = 0; } | ||
294 | if (isset($gradient_info['info']['x2'])) { $x2 = $gradient_info['info']['x2']; } | ||
295 | else { $x2 = 1; } | ||
296 | if (isset($gradient_info['info']['y2'])) { $y2 = $gradient_info['info']['y2']; } | ||
297 | else { $y2 = 0; } | ||
298 | |||
299 | if (stristr($x1, '%')!== false) { $x1 = ($x1+0)/100; } | ||
300 | if (stristr($x2, '%')!== false) { $x2 = ($x2+0)/100; } | ||
301 | if (stristr($y1, '%')!== false) { $y1 = ($y1+0)/100; } | ||
302 | if (stristr($y2, '%')!== false) { $y2 = ($y2+0)/100; } | ||
303 | |||
304 | // mPDF 5.0.042 | ||
305 | $bboxw = $w; | ||
306 | $bboxh = $h; | ||
307 | $usex = $x_offset; | ||
308 | $usey = $y_offset; | ||
309 | $usew = $bboxw; | ||
310 | $useh = $bboxh; | ||
311 | if (isset($gradient_info['units']) && strtolower($gradient_info['units'])=='userspaceonuse') { | ||
312 | $angle = rad2deg(atan2(($gradient_info['info']['y2']-$gradient_info['info']['y1']), ($gradient_info['info']['x2']-$gradient_info['info']['x1']))); | ||
313 | if ($angle < 0) { $angle += 360; } | ||
314 | else if ($angle > 360) { $angle -= 360; } | ||
315 | if ($angle!=0 && $angle!=360 && $angle!=90 && $angle!=180 && $angle!=270) { | ||
316 | if ($w >= $h) { | ||
317 | $y1 *= $h/$w ; | ||
318 | $y2 *= $h/$w ; | ||
319 | $usew = $useh = $bboxw; | ||
320 | } | ||
321 | else { | ||
322 | $x1 *= $w/$h ; | ||
323 | $x2 *= $w/$h ; | ||
324 | $usew = $useh = $bboxh; | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | $a = $usew; // width | ||
329 | $d = -$useh; // height | ||
330 | $e = $usex; // x- offset | ||
331 | $f = -$usey; // -y-offset | ||
332 | |||
333 | $return .= sprintf('%.3F 0 0 %.3F %.3F %.3F cm ', $a*$this->kp, $d*$this->kp, $e*$this->kp, $f*$this->kp); | ||
334 | |||
335 | // mPDF 5.0.039 | ||
336 | if (isset($gradient_info['units']) && strtolower($gradient_info['units'])=='objectboundingbox') { | ||
337 | if ($transformations) { $return .= $transformations; } | ||
338 | } | ||
339 | |||
340 | // mPDF 5.0.020 | ||
341 | $trans = false; | ||
342 | |||
343 | // mPDF 5.0.040 | ||
344 | if ($spread=='R' || $spread=='F') { // Repeat / Reflect | ||
345 | $offs = array(); | ||
346 | for($i=0;$i<$ns;$i++) { | ||
347 | $offs[$i] = $gradient_info['color'][$i]['offset']; | ||
348 | } | ||
349 | $gp = 0; | ||
350 | $inside=true; | ||
351 | while($inside) { | ||
352 | $gp++; | ||
353 | for($i=0;$i<$ns;$i++) { | ||
354 | if ($spread=='F' && ($gp % 2) == 1) { // Reflect | ||
355 | $gradient_info['color'][(($ns*$gp)+$i)] = $gradient_info['color'][(($ns*($gp-1))+($ns-$i-1))]; | ||
356 | $tmp = $gp+(1-$offs[($ns-$i-1)]) ; | ||
357 | $gradient_info['color'][(($ns*$gp)+$i)]['offset'] = $tmp; | ||
358 | } | ||
359 | else { // Reflect | ||
360 | $gradient_info['color'][(($ns*$gp)+$i)] = $gradient_info['color'][$i]; | ||
361 | $tmp = $gp+$offs[$i] ; | ||
362 | $gradient_info['color'][(($ns*$gp)+$i)]['offset'] = $tmp; | ||
363 | } | ||
364 | // IF STILL INSIDE BOX OR STILL VALID | ||
365 | // Point on axis to test | ||
366 | $px1 = $x1 + ($x2-$x1)*$tmp; | ||
367 | $py1 = $y1 + ($y2-$y1)*$tmp; | ||
368 | // Get perpendicular axis | ||
369 | $alpha = atan2($y2-$y1, $x2-$x1); | ||
370 | $alpha += M_PI/2; // rotate 90 degrees | ||
371 | // Get arbitrary point to define line perpendicular to axis | ||
372 | $px2 = $px1+cos($alpha); | ||
373 | $py2 = $py1+sin($alpha); | ||
374 | |||
375 | $res1 = _testIntersect($px1, $py1, $px2, $py2, 0, 0, 0, 1); // $x=0 vert axis | ||
376 | $res2 = _testIntersect($px1, $py1, $px2, $py2, 1, 0, 1, 1); // $x=1 vert axis | ||
377 | $res3 = _testIntersect($px1, $py1, $px2, $py2, 0, 0, 1, 0); // $y=0 horiz axis | ||
378 | $res4 = _testIntersect($px1, $py1, $px2, $py2, 0, 1, 1, 1); // $y=1 horiz axis | ||
379 | if (!$res1 && !$res2 && !$res3 && !$res4) { $inside = false; } | ||
380 | } | ||
381 | } | ||
382 | |||
383 | $inside=true; | ||
384 | $gp = 0; | ||
385 | while($inside) { | ||
386 | $gp++; | ||
387 | $newarr = array(); | ||
388 | for($i=0;$i<$ns;$i++) { | ||
389 | if ($spread=='F') { // Reflect | ||
390 | $newarr[$i] = $gradient_info['color'][($ns-$i-1)]; | ||
391 | if (($gp % 2) == 1) { | ||
392 | $tmp = -$gp+(1-$offs[($ns-$i-1)]); | ||
393 | $newarr[$i]['offset'] = $tmp; | ||
394 | } | ||
395 | else { | ||
396 | $tmp = -$gp+$offs[$i]; | ||
397 | $newarr[$i]['offset'] = $tmp; | ||
398 | } | ||
399 | } | ||
400 | else { // Reflect | ||
401 | $newarr[$i] = $gradient_info['color'][$i]; | ||
402 | $tmp = -$gp+$offs[$i]; | ||
403 | $newarr[$i]['offset'] = $tmp; | ||
404 | } | ||
405 | |||
406 | // IF STILL INSIDE BOX OR STILL VALID | ||
407 | // Point on axis to test | ||
408 | $px1 = $x1 + ($x2-$x1)*$tmp; | ||
409 | $py1 = $y1 + ($y2-$y1)*$tmp; | ||
410 | // Get perpendicular axis | ||
411 | $alpha = atan2($y2-$y1, $x2-$x1); | ||
412 | $alpha += M_PI/2; // rotate 90 degrees | ||
413 | // Get arbitrary point to define line perpendicular to axis | ||
414 | $px2 = $px1+cos($alpha); | ||
415 | $py2 = $py1+sin($alpha); | ||
416 | |||
417 | $res1 = _testIntersect($px1, $py1, $px2, $py2, 0, 0, 0, 1); // $x=0 vert axis | ||
418 | $res2 = _testIntersect($px1, $py1, $px2, $py2, 1, 0, 1, 1); // $x=1 vert axis | ||
419 | $res3 = _testIntersect($px1, $py1, $px2, $py2, 0, 0, 1, 0); // $y=0 horiz axis | ||
420 | $res4 = _testIntersect($px1, $py1, $px2, $py2, 0, 1, 1, 1); // $y=1 horiz axis | ||
421 | if (!$res1 && !$res2 && !$res3 && !$res4) { $inside = false; } | ||
422 | } | ||
423 | for($i=($ns-1);$i>=0;$i--) { | ||
424 | if (isset($newarr[$i]['offset'])) array_unshift($gradient_info['color'], $newarr[$i]); | ||
425 | } | ||
426 | } | ||
427 | } | ||
428 | |||
429 | // mPDF 4.4.007 Gradient STOPs | ||
430 | $stops = count($gradient_info['color']); | ||
431 | if ($stops < 2) { return ''; } | ||
432 | |||
433 | // mPDF 5.0.042 | ||
434 | $range = $gradient_info['color'][count($gradient_info['color'])-1]['offset']-$gradient_info['color'][0]['offset']; | ||
435 | $min = $gradient_info['color'][0]['offset']; | ||
436 | |||
437 | for ($i=0; $i<($stops); $i++) { | ||
438 | // mPDF 5.0.051 | ||
439 | if (!$gradient_info['color'][$i]['color']) { | ||
440 | if ($gradient_info['colorspace']=='RGB') $gradient_info['color'][$i]['color'] = '0 0 0'; | ||
441 | else if ($gradient_info['colorspace']=='Gray') $gradient_info['color'][$i]['color'] = '0'; | ||
442 | else if ($gradient_info['colorspace']=='CMYK') $gradient_info['color'][$i]['color'] = '1 1 1 1'; | ||
443 | } | ||
444 | $offset = ($gradient_info['color'][$i]['offset'] - $min)/$range; | ||
445 | $this->mpdf_ref->gradients[$n]['stops'][] = array( | ||
446 | 'col' => $gradient_info['color'][$i]['color'], | ||
447 | 'opacity' => $gradient_info['color'][$i]['opacity'], | ||
448 | 'offset' => $offset); | ||
449 | if ($gradient_info['color'][$i]['opacity']<1) { $trans = true; } | ||
450 | } | ||
451 | $grx1 = $x1 + ($x2-$x1)*$gradient_info['color'][0]['offset']; | ||
452 | $gry1 = $y1 + ($y2-$y1)*$gradient_info['color'][0]['offset']; | ||
453 | $grx2 = $x1 + ($x2-$x1)*$gradient_info['color'][count($gradient_info['color'])-1]['offset']; | ||
454 | $gry2 = $y1 + ($y2-$y1)*$gradient_info['color'][count($gradient_info['color'])-1]['offset']; | ||
455 | |||
456 | $this->mpdf_ref->gradients[$n]['coords']=array($grx1, $gry1, $grx2, $gry2); | ||
457 | |||
458 | $this->mpdf_ref->gradients[$n]['colorspace'] = $gradient_info['colorspace']; // mPDF 5.0.051 | ||
459 | |||
460 | $this->mpdf_ref->gradients[$n]['type'] = 2; | ||
461 | $this->mpdf_ref->gradients[$n]['fo'] = true; | ||
462 | |||
463 | $this->mpdf_ref->gradients[$n]['extend']=array('true','true'); | ||
464 | if ($trans) { | ||
465 | $this->mpdf_ref->gradients[$n]['trans'] = true; | ||
466 | $return .= ' /TGS'.($n).' gs '; | ||
467 | } | ||
468 | $return .= ' /Sh'.($n).' sh '; | ||
469 | $return .= " Q\n"; | ||
470 | } | ||
471 | else if ($gradient_info['type'] == 'radial'){ | ||
472 | // mPDF 4.4.003 | ||
473 | if (isset($gradient_info['units']) && strtolower($gradient_info['units'])=='userspaceonuse') { | ||
474 | if ($w > $h) { $h = $w; } | ||
475 | else { $w = $h; } | ||
476 | if (isset($gradient_info['info']['x0'])) { $gradient_info['info']['x0'] = ($gradient_info['info']['x0']-$x_offset) / $w; } | ||
477 | if (isset($gradient_info['info']['y0'])) { $gradient_info['info']['y0'] = ($gradient_info['info']['y0']-$y_offset) / $h; } | ||
478 | if (isset($gradient_info['info']['x1'])) { $gradient_info['info']['x1'] = ($gradient_info['info']['x1']-$x_offset) / $w; } | ||
479 | if (isset($gradient_info['info']['y1'])) { $gradient_info['info']['y1'] = ($gradient_info['info']['y1']-$y_offset) / $h; } | ||
480 | if (isset($gradient_info['info']['r'])) { $gradient_info['info']['rx'] = $gradient_info['info']['r'] / $w; } | ||
481 | if (isset($gradient_info['info']['r'])) { $gradient_info['info']['ry'] = $gradient_info['info']['r'] / $h; } | ||
482 | } | ||
483 | |||
484 | if ($gradient_info['info']['x0'] || $gradient_info['info']['x0']===0) { $x0 = $gradient_info['info']['x0']; } | ||
485 | else { $x0 = 0.5; } | ||
486 | if ($gradient_info['info']['y0'] || $gradient_info['info']['y0']===0) { $y0 = $gradient_info['info']['y0']; } | ||
487 | else { $y0 = 0.5; } | ||
488 | if ($gradient_info['info']['rx'] || $gradient_info['info']['rx']===0) { $rx = $gradient_info['info']['rx']; } | ||
489 | else if ($gradient_info['info']['r'] || $gradient_info['info']['r']===0) { $rx = $gradient_info['info']['r']; } | ||
490 | else { $rx = 0.5; } | ||
491 | if ($gradient_info['info']['ry'] || $gradient_info['info']['ry']===0) { $ry = $gradient_info['info']['ry']; } | ||
492 | else if ($gradient_info['info']['r'] || $gradient_info['info']['r']===0) { $ry = $gradient_info['info']['r']; } | ||
493 | else { $ry = 0.5; } | ||
494 | if ($gradient_info['info']['x1'] || $gradient_info['info']['x1']===0) { $x1 = $gradient_info['info']['x1']; } | ||
495 | else { $x1 = $x0; } | ||
496 | if ($gradient_info['info']['y1'] || $gradient_info['info']['y1']===0) { $y1 = $gradient_info['info']['y1']; } | ||
497 | else { $y1 = $y0; } | ||
498 | |||
499 | if (stristr($x1, '%')!== false) { $x1 = ($x1+0)/100; } | ||
500 | if (stristr($x0, '%')!== false) { $x0 = ($x0+0)/100; } | ||
501 | if (stristr($y1, '%')!== false) { $y1 = ($y1+0)/100; } | ||
502 | if (stristr($y0, '%')!== false) { $y0 = ($y0+0)/100; } | ||
503 | if (stristr($rx, '%')!== false) { $rx = ($rx+0)/100; } | ||
504 | if (stristr($ry, '%')!== false) { $ry = ($ry+0)/100; } | ||
505 | |||
506 | // mPDF 5.0.043 | ||
507 | $bboxw = $w; | ||
508 | $bboxh = $h; | ||
509 | $usex = $x_offset; | ||
510 | $usey = $y_offset; | ||
511 | $usew = $bboxw; | ||
512 | $useh = $bboxh; | ||
513 | if (isset($gradient_info['units']) && strtolower($gradient_info['units'])=='userspaceonuse') { | ||
514 | $angle = rad2deg(atan2(($gradient_info['info']['y0']-$gradient_info['info']['y1']), ($gradient_info['info']['x0']-$gradient_info['info']['x1']))); | ||
515 | if ($angle < 0) { $angle += 360; } | ||
516 | else if ($angle > 360) { $angle -= 360; } | ||
517 | if ($angle!=0 && $angle!=360 && $angle!=90 && $angle!=180 && $angle!=270) { | ||
518 | if ($w >= $h) { | ||
519 | $y1 *= $h/$w ; | ||
520 | $y0 *= $h/$w ; | ||
521 | $rx *= $h/$w ; | ||
522 | $ry *= $h/$w ; | ||
523 | $usew = $useh = $bboxw; | ||
524 | } | ||
525 | else { | ||
526 | $x1 *= $w/$h ; | ||
527 | $x0 *= $w/$h ; | ||
528 | $rx *= $w/$h ; | ||
529 | $ry *= $w/$h ; | ||
530 | $usew = $useh = $bboxh; | ||
531 | } | ||
532 | } | ||
533 | } | ||
534 | $a = $usew; // width | ||
535 | $d = -$useh; // height | ||
536 | $e = $usex; // x- offset | ||
537 | $f = -$usey; // -y-offset | ||
538 | |||
539 | $r = $rx; | ||
540 | |||
541 | |||
542 | $return .= sprintf('%.3F 0 0 %.3F %.3F %.3F cm ', $a*$this->kp, $d*$this->kp, $e*$this->kp, $f*$this->kp); | ||
543 | |||
544 | // mPDF 5.0.039 | ||
545 | if (isset($gradient_info['units']) && strtolower($gradient_info['units'])=='objectboundingbox') { | ||
546 | if ($transformations) { $return .= $transformations; } | ||
547 | } | ||
548 | |||
549 | // x1 and y1 (fx, fy) should be inside the circle defined by x0 y0 and r else error in mPDF | ||
550 | while (pow(($x1-$x0),2) + pow(($y1 - $y0),2) >= pow($r,2)) { $r += 0.05; } | ||
551 | |||
552 | // mPDF 5.0.040 | ||
553 | if ($spread=='R' || $spread=='F') { // Repeat / Reflect | ||
554 | $offs = array(); | ||
555 | for($i=0;$i<$ns;$i++) { | ||
556 | $offs[$i] = $gradient_info['color'][$i]['offset']; | ||
557 | } | ||
558 | $gp = 0; | ||
559 | $inside=true; | ||
560 | while($inside) { | ||
561 | $gp++; | ||
562 | for($i=0;$i<$ns;$i++) { | ||
563 | if ($spread=='F' && ($gp % 2) == 1) { // Reflect | ||
564 | $gradient_info['color'][(($ns*$gp)+$i)] = $gradient_info['color'][(($ns*($gp-1))+($ns-$i-1))]; | ||
565 | $tmp = $gp+(1-$offs[($ns-$i-1)]) ; | ||
566 | $gradient_info['color'][(($ns*$gp)+$i)]['offset'] = $tmp; | ||
567 | } | ||
568 | else { // Reflect | ||
569 | $gradient_info['color'][(($ns*$gp)+$i)] = $gradient_info['color'][$i]; | ||
570 | $tmp = $gp+$offs[$i] ; | ||
571 | $gradient_info['color'][(($ns*$gp)+$i)]['offset'] = $tmp; | ||
572 | } | ||
573 | // IF STILL INSIDE BOX OR STILL VALID | ||
574 | // TEST IF circle (perimeter) intersects with | ||
575 | // or is enclosed | ||
576 | // Point on axis to test | ||
577 | $px = $x1 + ($x0-$x1)*$tmp; | ||
578 | $py = $y1 + ($y0-$y1)*$tmp; | ||
579 | $pr = $r*$tmp; | ||
580 | $res = _testIntersectCircle($px, $py, $pr); | ||
581 | if (!$res) { $inside = false; } | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | |||
586 | // mPDF 4.4.007 Gradient STOPs | ||
587 | $stops = count($gradient_info['color']); | ||
588 | if ($stops < 2) { return ''; } | ||
589 | |||
590 | // mPDF 5.0.043 | ||
591 | $range = $gradient_info['color'][count($gradient_info['color'])-1]['offset']-$gradient_info['color'][0]['offset']; | ||
592 | $min = $gradient_info['color'][0]['offset']; | ||
593 | |||
594 | for ($i=0; $i<($stops); $i++) { | ||
595 | // mPDF 5.0.051 | ||
596 | if (!$gradient_info['color'][$i]['color']) { | ||
597 | if ($gradient_info['colorspace']=='RGB') $gradient_info['color'][$i]['color'] = '0 0 0'; | ||
598 | else if ($gradient_info['colorspace']=='Gray') $gradient_info['color'][$i]['color'] = '0'; | ||
599 | else if ($gradient_info['colorspace']=='CMYK') $gradient_info['color'][$i]['color'] = '1 1 1 1'; | ||
600 | } | ||
601 | $offset = ($gradient_info['color'][$i]['offset'] - $min)/$range; | ||
602 | $this->mpdf_ref->gradients[$n]['stops'][] = array( | ||
603 | 'col' => $gradient_info['color'][$i]['color'], | ||
604 | 'opacity' => $gradient_info['color'][$i]['opacity'], | ||
605 | 'offset' => $offset); | ||
606 | if ($gradient_info['color'][$i]['opacity']<1) { $trans = true; } | ||
607 | } | ||
608 | $grx1 = $x1 + ($x0-$x1)*$gradient_info['color'][0]['offset']; | ||
609 | $gry1 = $y1 + ($y0-$y1)*$gradient_info['color'][0]['offset']; | ||
610 | $grx2 = $x1 + ($x0-$x1)*$gradient_info['color'][count($gradient_info['color'])-1]['offset']; | ||
611 | $gry2 = $y1 + ($y0-$y1)*$gradient_info['color'][count($gradient_info['color'])-1]['offset']; | ||
612 | $grir = $r*$gradient_info['color'][0]['offset']; | ||
613 | $grr = $r*$gradient_info['color'][count($gradient_info['color'])-1]['offset']; | ||
614 | |||
615 | $this->mpdf_ref->gradients[$n]['coords']=array($grx1, $gry1, $grx2, $gry2, abs($grr), abs($grir) ); | ||
616 | |||
617 | $grx1 = $x1 + ($x0-$x1)*$first_stop; | ||
618 | $gry1 = $y1 + ($y0-$y1)*$first_stop; | ||
619 | $grx2 = $x1 + ($x0-$x1)*$last_stop; | ||
620 | $gry2 = $y1 + ($y0-$y1)*$last_stop; | ||
621 | $grir = $r*$first_stop; | ||
622 | $grr = $r*$last_stop; | ||
623 | $this->mpdf_ref->gradients[$n]['colorspace'] = $gradient_info['colorspace']; // mPDF 5.0.051 | ||
624 | |||
625 | $this->mpdf_ref->gradients[$n]['type'] = 3; | ||
626 | $this->mpdf_ref->gradients[$n]['fo'] = true; | ||
627 | |||
628 | $this->mpdf_ref->gradients[$n]['extend']=array('true','true'); | ||
629 | if ($trans) { | ||
630 | $this->mpdf_ref->gradients[$n]['trans'] = true; | ||
631 | $return .= ' /TGS'.($n).' gs '; | ||
632 | } | ||
633 | $return .= ' /Sh'.($n).' sh '; | ||
634 | $return .= " Q\n"; | ||
635 | |||
636 | |||
637 | } | ||
638 | |||
639 | return $return; | ||
640 | } | ||
641 | |||
642 | |||
643 | function svgOffset ($attribs){ | ||
644 | // save all <svg> tag attributes | ||
645 | $this->svg_attribs = $attribs; | ||
646 | if(isset($this->svg_attribs['viewBox'])) { | ||
647 | $vb = preg_split('/\s+/is', trim($this->svg_attribs['viewBox'])); | ||
648 | if (count($vb)==4) { | ||
649 | $this->svg_info['x'] = $vb[0]; | ||
650 | $this->svg_info['y'] = $vb[1]; | ||
651 | $this->svg_info['w'] = $vb[2]; | ||
652 | $this->svg_info['h'] = $vb[3]; | ||
653 | // return; // mPDF 5.0.005 | ||
654 | } | ||
655 | } | ||
656 | |||
657 | $svg_w = $this->mpdf_ref->ConvertSize($attribs['width']); // mm (interprets numbers as pixels) | ||
658 | $svg_h = $this->mpdf_ref->ConvertSize($attribs['height']); // mm | ||
659 | |||
660 | ///* | ||
661 | // mPDF 5.0.005 | ||
662 | if ($this->svg_info['w']) { // if 'w' set by viewBox | ||
663 | if ($svg_w) { // if width also set, use these values to determine to set size of "pixel" | ||
664 | $this->kp *= ($svg_w/0.2645) / $this->svg_info['w']; | ||
665 | $this->kf = ($svg_w/0.2645) / $this->svg_info['w']; // mPDF 5.0.039 | ||
666 | } | ||
667 | else if ($svg_h) { | ||
668 | $this->kp *= ($svg_h/0.2645) / $this->svg_info['h']; | ||
669 | $this->kf = ($svg_h/0.2645) / $this->svg_info['h']; // mPDF 5.0.039 | ||
670 | } | ||
671 | return; | ||
672 | } | ||
673 | //*/ | ||
674 | |||
675 | // Added to handle file without height or width specified | ||
676 | if (!$svg_w && !$svg_h) { $svg_w = $svg_h = $this->mpdf_ref->blk[$this->mpdf_ref->blklvl]['inner_width'] ; } // DEFAULT | ||
677 | if (!$svg_w) { $svg_w = $svg_h; } | ||
678 | if (!$svg_h) { $svg_h = $svg_w; } | ||
679 | |||
680 | $this->svg_info['x'] = 0; | ||
681 | $this->svg_info['y'] = 0; | ||
682 | $this->svg_info['w'] = $svg_w/0.2645; // mm->pixels | ||
683 | $this->svg_info['h'] = $svg_h/0.2645; // mm->pixels | ||
684 | |||
685 | } | ||
686 | |||
687 | |||
688 | // | ||
689 | // check if points are within svg, if not, set to max | ||
690 | function svg_overflow($x,$y) | ||
691 | { | ||
692 | $x2 = $x; | ||
693 | $y2 = $y; | ||
694 | if(isset($this->svg_attribs['overflow'])) | ||
695 | { | ||
696 | if($this->svg_attribs['overflow'] == 'hidden') | ||
697 | { | ||
698 | // Not sure if this is supposed to strip off units, but since I dont use any I will omlt this step | ||
699 | $svg_w = preg_replace("/([0-9\.]*)(.*)/i","$1",$this->svg_attribs['width']); | ||
700 | $svg_h = preg_replace("/([0-9\.]*)(.*)/i","$1",$this->svg_attribs['height']); | ||
701 | |||
702 | // $xmax = floor($this->svg_attribs['width']); | ||
703 | $xmax = floor($svg_w); | ||
704 | $xmin = 0; | ||
705 | // $ymax = floor(($this->svg_attribs['height'] * -1)); | ||
706 | $ymax = floor(($svg_h * -1)); | ||
707 | $ymin = 0; | ||
708 | |||
709 | if($x > $xmax) $x2 = $xmax; // right edge | ||
710 | if($x < $xmin) $x2 = $xmin; // left edge | ||
711 | if($y < $ymax) $y2 = $ymax; // bottom | ||
712 | if($y > $ymin) $y2 = $ymin; // top | ||
713 | |||
714 | } | ||
715 | } | ||
716 | |||
717 | |||
718 | return array( 'x' => $x2, 'y' => $y2); | ||
719 | } | ||
720 | |||
721 | |||
722 | |||
723 | function svgDefineStyle($critere_style){ | ||
724 | |||
725 | $tmp = count($this->svg_style)-1; | ||
726 | $current_style = $this->svg_style[$tmp]; | ||
727 | |||
728 | unset($current_style['transformations']); | ||
729 | |||
730 | // TRANSFORM SCALE | ||
731 | $transformations = ''; | ||
732 | if (isset($critere_style['transform'])){ | ||
733 | preg_match_all('/(matrix|translate|scale|rotate|skewX|skewY)\((.*?)\)/is',$critere_style['transform'],$m); | ||
734 | if (count($m[0])) { | ||
735 | for($i=0; $i<count($m[0]); $i++) { | ||
736 | $c = strtolower($m[1][$i]); | ||
737 | $v = trim($m[2][$i]); | ||
738 | $vv = preg_split('/[ ,]+/',$v); | ||
739 | if ($c=='matrix' && count($vv)==6) { | ||
740 | // mPDF 5.0.039 | ||
741 | // Note angle of rotation is reversed (from SVG to PDF), so vv[1] and vv[2] are negated | ||
742 | $transformations .= sprintf(' %.3F %.3F %.3F %.3F %.3F %.3F cm ', $vv[0], -$vv[1], -$vv[2], $vv[3], $vv[4]*$this->kp, -$vv[5]*$this->kp); | ||
743 | |||
744 | /* | ||
745 | // The long way of doing this?? | ||
746 | // need to reverse angle of rotation from SVG to PDF | ||
747 | $sx=sqrt(pow($vv[0],2)+pow($vv[2],2)); | ||
748 | if ($vv[0] < 0) { $sx *= -1; } // change sign | ||
749 | $sy=sqrt(pow($vv[1],2)+pow($vv[3],2)); | ||
750 | if ($vv[3] < 0) { $sy *= -1; } // change sign | ||
751 | |||
752 | // rotation angle is | ||
753 | $t=atan2($vv[1],$vv[3]); | ||
754 | $t=atan2(-$vv[2],$vv[0]); // Should be the same value or skew has been applied | ||
755 | |||
756 | // Reverse angle | ||
757 | $t *= -1; | ||
758 | |||
759 | // Rebuild matrix | ||
760 | $ma = $sx * cos($t); | ||
761 | $mb = $sy * sin($t); | ||
762 | $mc = -$sx * sin($t); | ||
763 | $md = $sy * cos($t); | ||
764 | |||
765 | // $transformations .= sprintf(' %.3F %.3F %.3F %.3F %.3F %.3F cm ', $ma, $mb, $mc, $md, $vv[4]*$this->kp, -$vv[5]*$this->kp); | ||
766 | */ | ||
767 | |||
768 | } | ||
769 | else if ($c=='translate' && count($vv)) { | ||
770 | $tm[4] = $vv[0]; | ||
771 | if (count($vv)==2) { $t_y = -$vv[1]; } | ||
772 | else { $t_y = 0; } | ||
773 | $tm[5] = $t_y; | ||
774 | $transformations .= sprintf(' 1 0 0 1 %.3F %.3F cm ', $tm[4]*$this->kp, $tm[5]*$this->kp); | ||
775 | } | ||
776 | else if ($c=='scale' && count($vv)) { | ||
777 | if (count($vv)==2) { $s_y = $vv[1]; } | ||
778 | else { $s_y = $vv[0]; } | ||
779 | $tm[0] = $vv[0]; | ||
780 | $tm[3] = $s_y; | ||
781 | $transformations .= sprintf(' %.3F 0 0 %.3F 0 0 cm ', $tm[0], $tm[3]); | ||
782 | } | ||
783 | else if ($c=='rotate' && count($vv)) { | ||
784 | $tm[0] = cos(deg2rad(-$vv[0])); | ||
785 | $tm[1] = sin(deg2rad(-$vv[0])); | ||
786 | $tm[2] = -$tm[1]; | ||
787 | $tm[3] = $tm[0]; | ||
788 | if (count($vv)==3) { | ||
789 | $transformations .= sprintf(' 1 0 0 1 %.3F %.3F cm ', $vv[1]*$this->kp, -$vv[2]*$this->kp); | ||
790 | } | ||
791 | $transformations .= sprintf(' %.3F %.3F %.3F %.3F 0 0 cm ', $tm[0], $tm[1], $tm[2], $tm[3]); | ||
792 | if (count($vv)==3) { | ||
793 | $transformations .= sprintf(' 1 0 0 1 %.3F %.3F cm ', -$vv[1]*$this->kp, $vv[2]*$this->kp); | ||
794 | } | ||
795 | } | ||
796 | else if ($c=='skewx' && count($vv)) { | ||
797 | $tm[2] = tan(deg2rad(-$vv[0])); | ||
798 | $transformations .= sprintf(' 1 0 %.3F 1 0 0 cm ', $tm[2]); | ||
799 | } | ||
800 | else if ($c=='skewy' && count($vv)) { | ||
801 | $tm[1] = tan(deg2rad(-$vv[0])); | ||
802 | $transformations .= sprintf(' 1 %.3F 0 1 0 0 cm ', $tm[1]); | ||
803 | } | ||
804 | |||
805 | } | ||
806 | } | ||
807 | $current_style['transformations'] = $transformations; | ||
808 | } | ||
809 | |||
810 | if (isset($critere_style['style'])){ | ||
811 | if (preg_match('/fill:\s*rgb\((\d+),\s*(\d+),\s*(\d+)\)/i',$critere_style['style'], $m)) { // mPDF 5.7.2 | ||
812 | $current_style['fill'] = '#'.str_pad(dechex($m[1]), 2, "0", STR_PAD_LEFT).str_pad(dechex($m[2]), 2, "0", STR_PAD_LEFT).str_pad(dechex($m[3]), 2, "0", STR_PAD_LEFT); | ||
813 | } | ||
814 | else { $tmp = preg_replace("/(.*)fill:\s*([a-z0-9#_()]*|none)(.*)/i","$2",$critere_style['style']); // mPDF 4.4.003 | ||
815 | if ($tmp != $critere_style['style']){ $current_style['fill'] = $tmp; } | ||
816 | } | ||
817 | |||
818 | // mPDF 5.7.2 | ||
819 | if (preg_match("/[^-]opacity:\s*([a-z0-9.]*|none)/i",$critere_style['style'], $m) || | ||
820 | preg_match("/^opacity:\s*([a-z0-9.]*|none)/i",$critere_style['style'], $m)) { | ||
821 | $current_style['fill-opacity'] = $m[1]; | ||
822 | $current_style['stroke-opacity'] = $m[1]; | ||
823 | } | ||
824 | |||
825 | $tmp = preg_replace("/(.*)fill-opacity:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
826 | if ($tmp != $critere_style['style']){ $current_style['fill-opacity'] = $tmp;} | ||
827 | |||
828 | $tmp = preg_replace("/(.*)fill-rule:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
829 | if ($tmp != $critere_style['style']){ $current_style['fill-rule'] = $tmp;} | ||
830 | |||
831 | if (preg_match('/stroke:\s*rgb\((\d+),\s*(\d+),\s*(\d+)\)/',$critere_style['style'], $m)) { | ||
832 | $current_style['stroke'] = '#'.str_pad(dechex($m[1]), 2, "0", STR_PAD_LEFT).str_pad(dechex($m[2]), 2, "0", STR_PAD_LEFT).str_pad(dechex($m[3]), 2, "0", STR_PAD_LEFT); | ||
833 | } | ||
834 | else { $tmp = preg_replace("/(.*)stroke:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
835 | if ($tmp != $critere_style['style']){ $current_style['stroke'] = $tmp; } | ||
836 | } | ||
837 | |||
838 | $tmp = preg_replace("/(.*)stroke-linecap:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
839 | if ($tmp != $critere_style['style']){ $current_style['stroke-linecap'] = $tmp;} | ||
840 | |||
841 | $tmp = preg_replace("/(.*)stroke-linejoin:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
842 | if ($tmp != $critere_style['style']){ $current_style['stroke-linejoin'] = $tmp;} | ||
843 | |||
844 | $tmp = preg_replace("/(.*)stroke-miterlimit:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
845 | if ($tmp != $critere_style['style']){ $current_style['stroke-miterlimit'] = $tmp;} | ||
846 | |||
847 | $tmp = preg_replace("/(.*)stroke-opacity:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
848 | if ($tmp != $critere_style['style']){ $current_style['stroke-opacity'] = $tmp; } | ||
849 | |||
850 | $tmp = preg_replace("/(.*)stroke-width:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
851 | if ($tmp != $critere_style['style']){ $current_style['stroke-width'] = $tmp;} | ||
852 | |||
853 | // mPDF 4.4.003 | ||
854 | $tmp = preg_replace("/(.*)stroke-dasharray:\s*([a-z0-9., ]*|none)(.*)/i","$2",$critere_style['style']); | ||
855 | if ($tmp != $critere_style['style']){ $current_style['stroke-dasharray'] = $tmp;} | ||
856 | |||
857 | // mPDF 4.4.003 | ||
858 | $tmp = preg_replace("/(.*)stroke-dashoffset:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
859 | if ($tmp != $critere_style['style']){ $current_style['stroke-dashoffset'] = $tmp;} | ||
860 | |||
861 | } | ||
862 | // mPDF 5.7.2 | ||
863 | if(isset($critere_style['opacity'])){ | ||
864 | $current_style['fill-opacity'] = $critere_style['opacity']; | ||
865 | $current_style['stroke-opacity'] = $critere_style['opacity']; | ||
866 | } | ||
867 | |||
868 | if(isset($critere_style['fill'])){ | ||
869 | $current_style['fill'] = $critere_style['fill']; | ||
870 | } | ||
871 | |||
872 | if(isset($critere_style['fill-opacity'])){ | ||
873 | $current_style['fill-opacity'] = $critere_style['fill-opacity']; | ||
874 | } | ||
875 | |||
876 | if(isset($critere_style['fill-rule'])){ | ||
877 | $current_style['fill-rule'] = $critere_style['fill-rule']; | ||
878 | } | ||
879 | |||
880 | if(isset($critere_style['stroke'])){ | ||
881 | $current_style['stroke'] = $critere_style['stroke']; | ||
882 | } | ||
883 | |||
884 | if(isset($critere_style['stroke-linecap'])){ | ||
885 | $current_style['stroke-linecap'] = $critere_style['stroke-linecap']; | ||
886 | } | ||
887 | |||
888 | if(isset($critere_style['stroke-linejoin'])){ | ||
889 | $current_style['stroke-linejoin'] = $critere_style['stroke-linejoin']; | ||
890 | } | ||
891 | |||
892 | if(isset($critere_style['stroke-miterlimit'])){ | ||
893 | $current_style['stroke-miterlimit'] = $critere_style['stroke-miterlimit']; | ||
894 | } | ||
895 | |||
896 | if(isset($critere_style['stroke-opacity'])){ | ||
897 | $current_style['stroke-opacity'] = $critere_style['stroke-opacity']; | ||
898 | } | ||
899 | |||
900 | if(isset($critere_style['stroke-width'])){ | ||
901 | $current_style['stroke-width'] = $critere_style['stroke-width']; | ||
902 | } | ||
903 | |||
904 | // mPDF 4.4.003 | ||
905 | if(isset($critere_style['stroke-dasharray'])){ | ||
906 | $current_style['stroke-dasharray'] = $critere_style['stroke-dasharray']; | ||
907 | } | ||
908 | if(isset($critere_style['stroke-dashoffset'])){ | ||
909 | $current_style['stroke-dashoffset'] = $critere_style['stroke-dashoffset']; | ||
910 | } | ||
911 | |||
912 | // mPDF 4.4.005 Used as indirect setting for currentColor | ||
913 | if(isset($critere_style['color']) && $critere_style['color'] != 'inherit'){ | ||
914 | $current_style['color'] = $critere_style['color']; | ||
915 | } | ||
916 | |||
917 | return $current_style; | ||
918 | |||
919 | } | ||
920 | |||
921 | // | ||
922 | // Cette fonction ecrit le style dans le stream svg. | ||
923 | function svgStyle($critere_style, $attribs, $element){ | ||
924 | $path_style = ''; | ||
925 | if (substr_count($critere_style['fill'],'url')>0 && $element != 'line'){ | ||
926 | // | ||
927 | // couleur degradé | ||
928 | $id_gradient = preg_replace("/url\(#([\w_]*)\)/i","$1",$critere_style['fill']); | ||
929 | if ($id_gradient != $critere_style['fill']) { | ||
930 | if (isset($this->svg_gradient[$id_gradient])) { | ||
931 | $fill_gradient = $this->svgGradient($this->svg_gradient[$id_gradient], $attribs, $element); | ||
932 | if ($fill_gradient) { // mPDF 4.4.003 | ||
933 | $path_style = "q "; | ||
934 | $w = "W"; | ||
935 | $style .= 'N'; | ||
936 | } | ||
937 | } | ||
938 | } | ||
939 | |||
940 | } | ||
941 | // mPDF 4.4.005 Used as indirect setting for currentColor | ||
942 | else if (strtolower($critere_style['fill']) == 'currentcolor' && $element != 'line'){ | ||
943 | $col = $this->mpdf_ref->ConvertColor($critere_style['color']); | ||
944 | if ($col) { | ||
945 | // mPDF 5.0.051 | ||
946 | // mPDF 5.3.74 | ||
947 | if ($col{0}==5) { $critere_style['fill-opacity'] = ord($col{4}/100); } // RGBa | ||
948 | if ($col{0}==6) { $critere_style['fill-opacity'] = ord($col{5}/100); } // CMYKa | ||
949 | $path_style .= $this->mpdf_ref->SetFColor($col, true).' '; // mPDF 5.0.051 | ||
950 | $style .= 'F'; | ||
951 | } | ||
952 | } | ||
953 | else if ($critere_style['fill'] != 'none' && $element != 'line'){ | ||
954 | $col = $this->mpdf_ref->ConvertColor($critere_style['fill']); | ||
955 | if ($col) { | ||
956 | // mPDF 5.0.051 | ||
957 | // mPDF 5.3.74 | ||
958 | if ($col{0}==5) { $critere_style['fill-opacity'] = ord($col{4}/100); } // RGBa | ||
959 | if ($col{0}==6) { $critere_style['fill-opacity'] = ord($col{5}/100); } // CMYKa | ||
960 | $path_style .= $this->mpdf_ref->SetFColor($col, true).' '; // mPDF 5.0.051 | ||
961 | $style .= 'F'; | ||
962 | } | ||
963 | } | ||
964 | |||
965 | // mPDF 5.0.040 | ||
966 | if (substr_count($critere_style['stroke'],'url')>0){ | ||
967 | /* | ||
968 | // Cannot put a gradient on a "stroke" in PDF? | ||
969 | $id_gradient = preg_replace("/url\(#([\w_]*)\)/i","$1",$critere_style['stroke']); | ||
970 | if ($id_gradient != $critere_style['stroke']) { | ||
971 | if (isset($this->svg_gradient[$id_gradient])) { | ||
972 | $fill_gradient = $this->svgGradient($this->svg_gradient[$id_gradient], $attribs, $element); | ||
973 | if ($fill_gradient) { | ||
974 | $path_style = "q "; | ||
975 | $w = "W"; | ||
976 | $style .= 'D'; | ||
977 | } | ||
978 | } | ||
979 | } | ||
980 | */ | ||
981 | } | ||
982 | // mPDF 4.4.005 Used as indirect setting for currentColor | ||
983 | else if (strtolower($critere_style['stroke']) == 'currentcolor'){ | ||
984 | $col = $this->mpdf_ref->ConvertColor($critere_style['color']); | ||
985 | if ($col) { | ||
986 | // mPDF 5.0.051 | ||
987 | // mPDF 5.3.74 | ||
988 | if ($col{0}==5) { $critere_style['stroke-opacity'] = ord($col{4}/100); } // RGBa | ||
989 | if ($col{0}==6) { $critere_style['stroke-opacity'] = ord($col{5}/100); } // CMYKa | ||
990 | $path_style .= $this->mpdf_ref->SetDColor($col, true).' '; // mPDF 5.0.051 | ||
991 | $style .= 'D'; | ||
992 | $lw = $this->ConvertSVGSizePixels($critere_style['stroke-width']); | ||
993 | $path_style .= sprintf('%.3F w ',$lw*$this->kp); | ||
994 | } | ||
995 | } | ||
996 | else if ($critere_style['stroke'] != 'none'){ | ||
997 | $col = $this->mpdf_ref->ConvertColor($critere_style['stroke']); | ||
998 | if ($col) { | ||
999 | // mPDF 5.0.051 | ||
1000 | // mPDF 5.3.74 | ||
1001 | if ($col{0}==5) { $critere_style['stroke-opacity'] = ord($col{4}/100); } // RGBa | ||
1002 | if ($col{0}==6) { $critere_style['stroke-opacity'] = ord($col{5}/100); } // CMYKa | ||
1003 | $path_style .= $this->mpdf_ref->SetDColor($col, true).' '; // mPDF 5.0.051 | ||
1004 | $style .= 'D'; | ||
1005 | $lw = $this->ConvertSVGSizePixels($critere_style['stroke-width']); // mPDF 4.4.003 | ||
1006 | $path_style .= sprintf('%.3F w ',$lw*$this->kp); | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | |||
1011 | if ($critere_style['stroke'] != 'none'){ | ||
1012 | if ($critere_style['stroke-linejoin'] == 'miter'){ | ||
1013 | $path_style .= ' 0 j '; | ||
1014 | } | ||
1015 | else if ($critere_style['stroke-linejoin'] == 'round'){ | ||
1016 | $path_style .= ' 1 j '; | ||
1017 | } | ||
1018 | else if ($critere_style['stroke-linejoin'] == 'bevel'){ | ||
1019 | $path_style .= ' 2 j '; | ||
1020 | } | ||
1021 | |||
1022 | if ($critere_style['stroke-linecap'] == 'butt'){ | ||
1023 | $path_style .= ' 0 J '; | ||
1024 | } | ||
1025 | else if ($critere_style['stroke-linecap'] == 'round'){ | ||
1026 | $path_style .= ' 1 J '; | ||
1027 | } | ||
1028 | else if ($critere_style['stroke-linecap'] == 'square'){ | ||
1029 | $path_style .= ' 2 J '; | ||
1030 | } | ||
1031 | |||
1032 | if (isset($critere_style['stroke-miterlimit'])){ | ||
1033 | if ($critere_style['stroke-miterlimit'] == 'none'){ | ||
1034 | } | ||
1035 | else if (preg_match('/^[\d.]+$/',$critere_style['stroke-miterlimit'])) { | ||
1036 | $path_style .= sprintf('%.2F M ',$critere_style['stroke-miterlimit']); | ||
1037 | } | ||
1038 | } | ||
1039 | // mPDF 4.4.003 | ||
1040 | if (isset($critere_style['stroke-dasharray'])){ | ||
1041 | $off = 0; | ||
1042 | $d = preg_split('/[ ,]/',$critere_style['stroke-dasharray']); | ||
1043 | if (count($d) == 1 && $d[0]==0) { | ||
1044 | $path_style .= '[] 0 d '; | ||
1045 | } | ||
1046 | else { | ||
1047 | if (count($d) % 2 == 1) { $d = array_merge($d, $d); } // 5, 3, 1 => 5,3,1,5,3,1 OR 3 => 3,3 | ||
1048 | $arr = ''; | ||
1049 | for($i=0; $i<count($d); $i+=2) { | ||
1050 | $arr .= sprintf('%.3F %.3F ', $d[$i]*$this->kp, $d[$i+1]*$this->kp); | ||
1051 | } | ||
1052 | if (isset($critere_style['stroke-dashoffset'])){ $off = $critere_style['stroke-dashoffset'] + 0; } | ||
1053 | $path_style .= sprintf('[%s] %.3F d ', $arr, $off*$this->kp); | ||
1054 | } | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | // mPDF 4.4.003 | ||
1059 | if ($critere_style['fill-rule']=='evenodd') { $fr = '*'; } | ||
1060 | else { $fr = ''; } | ||
1061 | |||
1062 | // mPDF 4.4.003 | ||
1063 | if (isset($critere_style['fill-opacity'])) { | ||
1064 | $opacity = 1; | ||
1065 | if ($critere_style['fill-opacity'] == 0) { $opacity = 0; } | ||
1066 | else if ($critere_style['fill-opacity'] > 1) { $opacity = 1; } | ||
1067 | else if ($critere_style['fill-opacity'] > 0) { $opacity = $critere_style['fill-opacity']; } | ||
1068 | else if ($critere_style['fill-opacity'] < 0) { $opacity = 0; } | ||
1069 | $gs = $this->mpdf_ref->AddExtGState(array('ca'=>$opacity, 'BM'=>'/Normal')); | ||
1070 | $this->mpdf_ref->extgstates[$gs]['fo'] = true; // mPDF 5.0.039 | ||
1071 | $path_style .= sprintf(' /GS%d gs ', $gs); | ||
1072 | } | ||
1073 | |||
1074 | // mPDF 4.4.003 | ||
1075 | if (isset($critere_style['stroke-opacity'])) { | ||
1076 | $opacity = 1; | ||
1077 | if ($critere_style['stroke-opacity'] == 0) { $opacity = 0; } | ||
1078 | else if ($critere_style['stroke-opacity'] > 1) { $opacity = 1; } | ||
1079 | else if ($critere_style['stroke-opacity'] > 0) { $opacity = $critere_style['stroke-opacity']; } | ||
1080 | else if ($critere_style['stroke-opacity'] < 0) { $opacity = 0; } | ||
1081 | $gs = $this->mpdf_ref->AddExtGState(array('CA'=>$opacity, 'BM'=>'/Normal')); | ||
1082 | $this->mpdf_ref->extgstates[$gs]['fo'] = true; // mPDF 5.0.039 | ||
1083 | $path_style .= sprintf(' /GS%d gs ', $gs); | ||
1084 | } | ||
1085 | |||
1086 | switch ($style){ | ||
1087 | case 'F': | ||
1088 | $op = 'f'; | ||
1089 | break; | ||
1090 | case 'FD': | ||
1091 | $op = 'B'; | ||
1092 | break; | ||
1093 | case 'ND': | ||
1094 | $op = 'S'; | ||
1095 | break; | ||
1096 | case 'D': | ||
1097 | $op = 'S'; | ||
1098 | break; | ||
1099 | default: | ||
1100 | $op = 'n'; | ||
1101 | } | ||
1102 | |||
1103 | // mPDF 5.0 | ||
1104 | $prestyle = $path_style.' '; | ||
1105 | $poststyle = $w.' '. $op.$fr.' '.$fill_gradient."\n"; | ||
1106 | return array($prestyle,$poststyle); | ||
1107 | |||
1108 | } | ||
1109 | |||
1110 | // | ||
1111 | // fonction retracant les <path /> | ||
1112 | function svgPath($command, $arguments){ | ||
1113 | $path_cmd = ''; | ||
1114 | $newsubpath = false; // mPDF 4.4.003 | ||
1115 | // mPDF 5.0.039 | ||
1116 | $minl = $this->pathBBox[0]; | ||
1117 | $mint = $this->pathBBox[1]; | ||
1118 | $maxr = $this->pathBBox[2]+$this->pathBBox[0]; | ||
1119 | $maxb = $this->pathBBox[3]+$this->pathBBox[1]; | ||
1120 | // mPDF 5.0.040 | ||
1121 | $start = array($this->xbase, -$this->ybase); | ||
1122 | |||
1123 | // mPDF 4.4.003 | ||
1124 | preg_match_all('/[\-^]?[\d.]+(e[\-]?[\d]+){0,1}/i', $arguments, $a, PREG_SET_ORDER); | ||
1125 | |||
1126 | // if the command is a capital letter, the coords go absolute, otherwise relative | ||
1127 | if(strtolower($command) == $command) $relative = true; | ||
1128 | else $relative = false; | ||
1129 | |||
1130 | |||
1131 | $ile_argumentow = count($a); | ||
1132 | |||
1133 | // each command may have different needs for arguments [1 to 8] | ||
1134 | |||
1135 | switch(strtolower($command)){ | ||
1136 | case 'm': // move | ||
1137 | for($i = 0; $i<$ile_argumentow; $i+=2){ | ||
1138 | $x = $a[$i][0]; | ||
1139 | $y = $a[$i+1][0]; | ||
1140 | if($relative){ | ||
1141 | $pdfx = ($this->xbase + $x); | ||
1142 | $pdfy = ($this->ybase - $y); | ||
1143 | $this->xbase += $x; | ||
1144 | $this->ybase += -$y; | ||
1145 | } | ||
1146 | else{ | ||
1147 | $pdfx = $x; | ||
1148 | $pdfy = -$y ; | ||
1149 | $this->xbase = $x; | ||
1150 | $this->ybase = -$y; | ||
1151 | } | ||
1152 | $pdf_pt = $this->svg_overflow($pdfx,$pdfy); | ||
1153 | // mPDF 5.0.039 | ||
1154 | $minl = min($minl,$pdf_pt['x']); | ||
1155 | $maxr = max($maxr,$pdf_pt['x']); | ||
1156 | $mint = min($mint,-$pdf_pt['y']); | ||
1157 | $maxb = max($maxb,-$pdf_pt['y']); | ||
1158 | if($i == 0) $path_cmd .= sprintf('%.3F %.3F m ', $pdf_pt['x']*$this->kp, $pdf_pt['y']*$this->kp); | ||
1159 | else $path_cmd .= sprintf('%.3F %.3F l ', $pdf_pt['x']*$this->kp, $pdf_pt['y']*$this->kp); | ||
1160 | // mPDF 4.4.003 Save start points of subpath | ||
1161 | if ($this->subPathInit) { | ||
1162 | $this->spxstart = $this->xbase; | ||
1163 | $this->spystart = $this->ybase; | ||
1164 | $this->subPathInit = false; | ||
1165 | } | ||
1166 | } | ||
1167 | break; | ||
1168 | case 'l': // a simple line | ||
1169 | for($i = 0; $i<$ile_argumentow; $i+=2){ | ||
1170 | $x = ($a[$i][0]); | ||
1171 | $y = ($a[$i+1][0]); | ||
1172 | if($relative){ | ||
1173 | $pdfx = ($this->xbase + $x); | ||
1174 | $pdfy = ($this->ybase - $y); | ||
1175 | $this->xbase += $x; | ||
1176 | $this->ybase += -$y; | ||
1177 | } | ||
1178 | else{ | ||
1179 | $pdfx = $x ; | ||
1180 | $pdfy = -$y ; | ||
1181 | $this->xbase = $x; | ||
1182 | $this->ybase = -$y; | ||
1183 | } | ||
1184 | $pdf_pt = $this->svg_overflow($pdfx,$pdfy); | ||
1185 | // mPDF 5.0.039 | ||
1186 | $minl = min($minl,$pdf_pt['x']); | ||
1187 | $maxr = max($maxr,$pdf_pt['x']); | ||
1188 | $mint = min($mint,-$pdf_pt['y']); | ||
1189 | $maxb = max($maxb,-$pdf_pt['y']); | ||
1190 | $path_cmd .= sprintf('%.3F %.3F l ', $pdf_pt['x']*$this->kp, $pdf_pt['y']*$this->kp); | ||
1191 | } | ||
1192 | break; | ||
1193 | case 'h': // a very simple horizontal line | ||
1194 | for($i = 0; $i<$ile_argumentow; $i++){ | ||
1195 | $x = ($a[$i][0]); | ||
1196 | if($relative){ | ||
1197 | $y = 0; | ||
1198 | $pdfx = ($this->xbase + $x) ; | ||
1199 | $pdfy = ($this->ybase - $y) ; | ||
1200 | $this->xbase += $x; | ||
1201 | $this->ybase += -$y; | ||
1202 | } | ||
1203 | else{ | ||
1204 | $y = -$this->ybase; | ||
1205 | $pdfx = $x; | ||
1206 | $pdfy = -$y; | ||
1207 | $this->xbase = $x; | ||
1208 | $this->ybase = -$y; | ||
1209 | } | ||
1210 | $pdf_pt = $this->svg_overflow($pdfx,$pdfy); | ||
1211 | // mPDF 5.0.039 | ||
1212 | $minl = min($minl,$pdf_pt['x']); | ||
1213 | $maxr = max($maxr,$pdf_pt['x']); | ||
1214 | $mint = min($mint,-$pdf_pt['y']); | ||
1215 | $maxb = max($maxb,-$pdf_pt['y']); | ||
1216 | $path_cmd .= sprintf('%.3F %.3F l ', $pdf_pt['x']*$this->kp, $pdf_pt['y']*$this->kp); | ||
1217 | } | ||
1218 | break; | ||
1219 | case 'v': // the simplest line, vertical | ||
1220 | for($i = 0; $i<$ile_argumentow; $i++){ | ||
1221 | $y = ($a[$i][0]); | ||
1222 | if($relative){ | ||
1223 | $x = 0; | ||
1224 | $pdfx = ($this->xbase + $x); | ||
1225 | $pdfy = ($this->ybase - $y); | ||
1226 | $this->xbase += $x; | ||
1227 | $this->ybase += -$y; | ||
1228 | } | ||
1229 | else{ | ||
1230 | $x = $this->xbase; | ||
1231 | $pdfx = $x; | ||
1232 | $pdfy = -$y; | ||
1233 | $this->xbase = $x; | ||
1234 | $this->ybase = -$y; | ||
1235 | } | ||
1236 | $pdf_pt = $this->svg_overflow($pdfx,$pdfy); | ||
1237 | // mPDF 5.0.039 | ||
1238 | $minl = min($minl,$pdf_pt['x']); | ||
1239 | $maxr = max($maxr,$pdf_pt['x']); | ||
1240 | $mint = min($mint,-$pdf_pt['y']); | ||
1241 | $maxb = max($maxb,-$pdf_pt['y']); | ||
1242 | $path_cmd .= sprintf('%.3F %.3F l ', $pdf_pt['x']*$this->kp, $pdf_pt['y']*$this->kp); | ||
1243 | } | ||
1244 | break; | ||
1245 | case 's': // bezier with first vertex equal first control | ||
1246 | // mPDF 4.4.003 | ||
1247 | if (!($this->lastcommand == 'C' || $this->lastcommand == 'c' || $this->lastcommand == 'S' || $this->lastcommand == 's')) { | ||
1248 | $this->lastcontrolpoints = array(0,0); | ||
1249 | } | ||
1250 | for($i = 0; $i<$ile_argumentow; $i += 4){ | ||
1251 | $x1 = $this->lastcontrolpoints[0]; | ||
1252 | $y1 = $this->lastcontrolpoints[1]; | ||
1253 | $x2 = ($a[$i][0]); | ||
1254 | $y2 = ($a[$i+1][0]); | ||
1255 | $x = ($a[$i+2][0]); | ||
1256 | $y = ($a[$i+3][0]); | ||
1257 | if($relative){ | ||
1258 | $pdfx1 = ($this->xbase + $x1); | ||
1259 | $pdfy1 = ($this->ybase - $y1); | ||
1260 | $pdfx2 = ($this->xbase + $x2); | ||
1261 | $pdfy2 = ($this->ybase - $y2); | ||
1262 | $pdfx = ($this->xbase + $x); | ||
1263 | $pdfy = ($this->ybase - $y); | ||
1264 | $this->xbase += $x; | ||
1265 | $this->ybase += -$y; | ||
1266 | } | ||
1267 | else{ | ||
1268 | $pdfx1 = $this->xbase + $x1; | ||
1269 | $pdfy1 = $this->ybase -$y1; | ||
1270 | $pdfx2 = $x2; | ||
1271 | $pdfy2 = -$y2; | ||
1272 | $pdfx = $x; | ||
1273 | $pdfy = -$y; | ||
1274 | $this->xbase = $x; | ||
1275 | $this->ybase = -$y; | ||
1276 | } | ||
1277 | $this->lastcontrolpoints = array(($pdfx-$pdfx2),-($pdfy-$pdfy2)); // mPDF 4.4.003 always relative | ||
1278 | |||
1279 | $pdf_pt = $this->svg_overflow($pdfx,$pdfy); | ||
1280 | |||
1281 | // mPDF 5.0.040 | ||
1282 | $curves = array($pdfx1,-$pdfy1,$pdfx2,-$pdfy2,$pdfx,-$pdfy); | ||
1283 | $bx = calc_bezier_bbox($start, $curves); | ||
1284 | $minl = min($minl,$bx[0]); | ||
1285 | $maxr = max($maxr,$bx[2]); | ||
1286 | $mint = min($mint,$bx[1]); | ||
1287 | $maxb = max($maxb,$bx[3]); | ||
1288 | |||
1289 | if( ($pdf_pt['x'] != $pdfx) || ($pdf_pt['y'] != $pdfy) ) | ||
1290 | { | ||
1291 | $path_cmd .= sprintf('%.3F %.3F l ', $pdf_pt['x']*$this->kp, $pdf_pt['y']*$this->kp); | ||
1292 | } | ||
1293 | else | ||
1294 | { | ||
1295 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $pdfx1*$this->kp, $pdfy1*$this->kp, $pdfx2*$this->kp, $pdfy2*$this->kp, $pdfx*$this->kp, $pdfy*$this->kp); | ||
1296 | } | ||
1297 | |||
1298 | } | ||
1299 | break; | ||
1300 | case 'c': // bezier with second vertex equal second control | ||
1301 | for($i = 0; $i<$ile_argumentow; $i += 6){ | ||
1302 | $x1 = ($a[$i][0]); | ||
1303 | $y1 = ($a[$i+1][0]); | ||
1304 | $x2 = ($a[$i+2][0]); | ||
1305 | $y2 = ($a[$i+3][0]); | ||
1306 | $x = ($a[$i+4][0]); | ||
1307 | $y = ($a[$i+5][0]); | ||
1308 | |||
1309 | |||
1310 | if($relative){ | ||
1311 | $pdfx1 = ($this->xbase + $x1); | ||
1312 | $pdfy1 = ($this->ybase - $y1); | ||
1313 | $pdfx2 = ($this->xbase + $x2); | ||
1314 | $pdfy2 = ($this->ybase - $y2); | ||
1315 | $pdfx = ($this->xbase + $x); | ||
1316 | $pdfy = ($this->ybase - $y); | ||
1317 | $this->xbase += $x; | ||
1318 | $this->ybase += -$y; | ||
1319 | } | ||
1320 | else{ | ||
1321 | $pdfx1 = $x1; | ||
1322 | $pdfy1 = -$y1; | ||
1323 | $pdfx2 = $x2; | ||
1324 | $pdfy2 = -$y2; | ||
1325 | $pdfx = $x; | ||
1326 | $pdfy = -$y; | ||
1327 | $this->xbase = $x; | ||
1328 | $this->ybase = -$y; | ||
1329 | } | ||
1330 | $this->lastcontrolpoints = array(($pdfx-$pdfx2),-($pdfy-$pdfy2)); // mPDF 4.4.003 always relative | ||
1331 | // $pdf_pt2 = $this->svg_overflow($pdfx2,$pdfy2); | ||
1332 | // $pdf_pt1 = $this->svg_overflow($pdfx1,$pdfy1); | ||
1333 | $pdf_pt = $this->svg_overflow($pdfx,$pdfy); | ||
1334 | |||
1335 | // mPDF 5.0.040 | ||
1336 | $curves = array($pdfx1,-$pdfy1,$pdfx2,-$pdfy2,$pdfx,-$pdfy); | ||
1337 | $bx = calc_bezier_bbox($start, $curves); | ||
1338 | $minl = min($minl,$bx[0]); | ||
1339 | $maxr = max($maxr,$bx[2]); | ||
1340 | $mint = min($mint,$bx[1]); | ||
1341 | $maxb = max($maxb,$bx[3]); | ||
1342 | |||
1343 | if( ($pdf_pt['x'] != $pdfx) || ($pdf_pt['y'] != $pdfy) ) | ||
1344 | { | ||
1345 | $path_cmd .= sprintf('%.3F %.3F l ', $pdf_pt['x']*$this->kp, $pdf_pt['y']*$this->kp); | ||
1346 | } | ||
1347 | else | ||
1348 | { | ||
1349 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $pdfx1*$this->kp, $pdfy1*$this->kp, $pdfx2*$this->kp, $pdfy2*$this->kp, $pdfx*$this->kp, $pdfy*$this->kp); | ||
1350 | } | ||
1351 | |||
1352 | } | ||
1353 | break; | ||
1354 | |||
1355 | case 'q': // bezier quadratic avec point de control | ||
1356 | for($i = 0; $i<$ile_argumentow; $i += 4){ | ||
1357 | $x1 = ($a[$i][0]); | ||
1358 | $y1 = ($a[$i+1][0]); | ||
1359 | $x = ($a[$i+2][0]); | ||
1360 | $y = ($a[$i+3][0]); | ||
1361 | if($relative){ | ||
1362 | $pdfx = ($this->xbase + $x); | ||
1363 | $pdfy = ($this->ybase - $y); | ||
1364 | |||
1365 | $pdfx1 = ($this->xbase + ($x1*2/3)); | ||
1366 | $pdfy1 = ($this->ybase - ($y1*2/3)); | ||
1367 | // mPDF 4.4.003 | ||
1368 | $pdfx2 = $pdfx1 + 1/3 *($x); | ||
1369 | $pdfy2 = $pdfy1 + 1/3 *(-$y) ; | ||
1370 | |||
1371 | $this->xbase += $x; | ||
1372 | $this->ybase += -$y; | ||
1373 | } | ||
1374 | else{ | ||
1375 | $pdfx = $x; | ||
1376 | $pdfy = -$y; | ||
1377 | |||
1378 | $pdfx1 = ($this->xbase+(($x1-$this->xbase)*2/3)); | ||
1379 | $pdfy1 = ($this->ybase-(($y1+$this->ybase)*2/3)); | ||
1380 | |||
1381 | $pdfx2 = ($x+(($x1-$x)*2/3)); | ||
1382 | $pdfy2 = (-$y-(($y1-$y)*2/3)); | ||
1383 | |||
1384 | // mPDF 4.4.003 | ||
1385 | $pdfx2 = $pdfx1 + 1/3 *($x - $this->xbase); | ||
1386 | $pdfy2 = $pdfy1 + 1/3 *(-$y - $this->ybase) ; | ||
1387 | |||
1388 | $this->xbase = $x; | ||
1389 | $this->ybase = -$y; | ||
1390 | } | ||
1391 | $this->lastcontrolpoints = array(($pdfx-$pdfx2),-($pdfy-$pdfy2)); // mPDF 4.4.003 always relative | ||
1392 | |||
1393 | $pdf_pt = $this->svg_overflow($pdfx,$pdfy); | ||
1394 | |||
1395 | // mPDF 5.0.040 | ||
1396 | $curves = array($pdfx1,-$pdfy1,$pdfx2,-$pdfy2,$pdfx,-$pdfy); | ||
1397 | $bx = calc_bezier_bbox($start, $curves); | ||
1398 | $minl = min($minl,$bx[0]); | ||
1399 | $maxr = max($maxr,$bx[2]); | ||
1400 | $mint = min($mint,$bx[1]); | ||
1401 | $maxb = max($maxb,$bx[3]); | ||
1402 | |||
1403 | if( ($pdf_pt['x'] != $pdfx) || ($pdf_pt['y'] != $pdfy) ) | ||
1404 | { | ||
1405 | $path_cmd .= sprintf('%.3F %.3F l ', $pdf_pt['x']*$this->kp, $pdf_pt['y']*$this->kp); | ||
1406 | } | ||
1407 | else | ||
1408 | { | ||
1409 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $pdfx1*$this->kp, $pdfy1*$this->kp, $pdfx2*$this->kp, $pdfy2*$this->kp, $pdfx*$this->kp, $pdfy*$this->kp); | ||
1410 | } | ||
1411 | } | ||
1412 | break; | ||
1413 | case 't': // bezier quadratic avec point de control simetrique a lancien point de control | ||
1414 | // mPDF 4.4.003 | ||
1415 | if (!($this->lastcommand == 'Q' || $this->lastcommand == 'q' || $this->lastcommand == 'T' || $this->lastcommand == 't')) { | ||
1416 | $this->lastcontrolpoints = array(0,0); | ||
1417 | } | ||
1418 | for($i = 0; $i<$ile_argumentow; $i += 2){ | ||
1419 | $x = ($a[$i][0]); | ||
1420 | $y = ($a[$i+1][0]); | ||
1421 | |||
1422 | $x1 = $this->lastcontrolpoints[0]; | ||
1423 | $y1 = $this->lastcontrolpoints[1]; | ||
1424 | |||
1425 | if($relative){ | ||
1426 | $pdfx = ($this->xbase + $x); | ||
1427 | $pdfy = ($this->ybase - $y); | ||
1428 | |||
1429 | $pdfx1 = ($this->xbase + ($x1)); // mPDF 4.4.003 | ||
1430 | $pdfy1 = ($this->ybase - ($y1)); // mPDF 4.4.003 | ||
1431 | // mPDF 4.4.003 | ||
1432 | $pdfx2 = $pdfx1 + 1/3 *($x); | ||
1433 | $pdfy2 = $pdfy1 + 1/3 *(-$y) ; | ||
1434 | |||
1435 | $this->xbase += $x; | ||
1436 | $this->ybase += -$y; | ||
1437 | } | ||
1438 | else{ | ||
1439 | $pdfx = $x; | ||
1440 | $pdfy = -$y; | ||
1441 | |||
1442 | $pdfx1 = ($this->xbase + ($x1)); // mPDF 4.4.003 | ||
1443 | $pdfy1 = ($this->ybase - ($y1)); // mPDF 4.4.003 | ||
1444 | // mPDF 4.4.003 | ||
1445 | $pdfx2 = $pdfx1 + 1/3 *($x - $this->xbase); | ||
1446 | $pdfy2 = $pdfy1 + 1/3 *(-$y - $this->ybase) ; | ||
1447 | |||
1448 | $this->xbase = $x; | ||
1449 | $this->ybase = -$y; | ||
1450 | } | ||
1451 | |||
1452 | $this->lastcontrolpoints = array(($pdfx-$pdfx2),-($pdfy-$pdfy2)); // mPDF 4.4.003 always relative | ||
1453 | |||
1454 | // mPDF 5.0.040 | ||
1455 | $curves = array($pdfx1,-$pdfy1,$pdfx2,-$pdfy2,$pdfx,-$pdfy); | ||
1456 | $bx = calc_bezier_bbox($start, $curves); | ||
1457 | $minl = min($minl,$bx[0]); | ||
1458 | $maxr = max($maxr,$bx[2]); | ||
1459 | $mint = min($mint,$bx[1]); | ||
1460 | $maxb = max($maxb,$bx[3]); | ||
1461 | |||
1462 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $pdfx1*$this->kp, $pdfy1*$this->kp, $pdfx2*$this->kp, $pdfy2*$this->kp, $pdfx*$this->kp, $pdfy*$this->kp); | ||
1463 | } | ||
1464 | |||
1465 | break; | ||
1466 | case 'a': // Elliptical arc | ||
1467 | for($i = 0; $i<$ile_argumentow; $i += 7){ | ||
1468 | $rx = ($a[$i][0]); | ||
1469 | $ry = ($a[$i+1][0]); | ||
1470 | $angle = ($a[$i+2][0]); //x-axis-rotation | ||
1471 | $largeArcFlag = ($a[$i+3][0]); | ||
1472 | $sweepFlag = ($a[$i+4][0]); | ||
1473 | $x2 = ($a[$i+5][0]); | ||
1474 | $y2 = ($a[$i+6][0]); | ||
1475 | $x1 = $this->xbase; | ||
1476 | $y1 = -$this->ybase; | ||
1477 | if($relative){ | ||
1478 | $x2 = $this->xbase + $x2; | ||
1479 | $y2 = -$this->ybase + $y2; | ||
1480 | $this->xbase += ($a[$i+5][0]); | ||
1481 | $this->ybase += -($a[$i+6][0]); | ||
1482 | } | ||
1483 | else{ | ||
1484 | $this->xbase = $x2; | ||
1485 | $this->ybase = -$y2; | ||
1486 | } | ||
1487 | // mPDF 5.0.039 // mPDF 5.0.040 | ||
1488 | list($pcmd, $bounds) = $this->Arcto($x1, $y1, $x2, $y2, $rx, $ry, $angle, $largeArcFlag, $sweepFlag); | ||
1489 | $minl = min($minl,$x2,min($bounds[0])); | ||
1490 | $maxr = max($maxr,$x2,max($bounds[0])); | ||
1491 | $mint = min($mint,$y2,min($bounds[1])); | ||
1492 | $maxb = max($maxb,$y2,max($bounds[1])); | ||
1493 | $path_cmd .= $pcmd; | ||
1494 | |||
1495 | } | ||
1496 | break; | ||
1497 | case'z': | ||
1498 | $path_cmd .= 'h '; | ||
1499 | // mPDF 4.4.003 | ||
1500 | $this->subPathInit = true; | ||
1501 | $newsubpath = true; | ||
1502 | $this->xbase = $this->spxstart; | ||
1503 | $this->ybase = $this->spystart; | ||
1504 | break; | ||
1505 | default: | ||
1506 | break; | ||
1507 | } | ||
1508 | |||
1509 | if (!$newsubpath) { $this->subPathInit = false; } // mPDF 4.4.003 | ||
1510 | $this->lastcommand = $command; | ||
1511 | // mPDF 5.0.039 | ||
1512 | $this->pathBBox[0] = $minl; | ||
1513 | $this->pathBBox[1] = $mint; | ||
1514 | $this->pathBBox[2] = $maxr - $this->pathBBox[0]; | ||
1515 | $this->pathBBox[3] = $maxb - $this->pathBBox[1]; | ||
1516 | return $path_cmd; | ||
1517 | |||
1518 | } | ||
1519 | |||
1520 | function Arcto($x1, $y1, $x2, $y2, $rx, $ry, $angle, $largeArcFlag, $sweepFlag) { | ||
1521 | |||
1522 | // mPDF 5.0.040 | ||
1523 | $bounds = array(0=>array($x1,$x2),1=>array($y1,$y2)); | ||
1524 | // 1. Treat out-of-range parameters as described in | ||
1525 | // http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes | ||
1526 | // If the endpoints (x1, y1) and (x2, y2) are identical, then this | ||
1527 | // is equivalent to omitting the elliptical arc segment entirely | ||
1528 | if ($x1 == $x2 && $y1 == $y2) return array('', $bounds); // mPD 5.0.040 | ||
1529 | |||
1530 | // If rX = 0 or rY = 0 then this arc is treated as a straight line | ||
1531 | // segment (a "lineto") joining the endpoints. | ||
1532 | if ($rx == 0.0 || $ry == 0.0) { | ||
1533 | // return array(Lineto(x2, y2), $bounds); // mPD 5.0.040 | ||
1534 | } | ||
1535 | |||
1536 | // If rX or rY have negative signs, these are dropped; the absolute | ||
1537 | // value is used instead. | ||
1538 | if ($rx<0.0) $rx = -$rx; | ||
1539 | if ($ry<0.0) $ry = -$ry; | ||
1540 | |||
1541 | // 2. convert to center parameterization as shown in | ||
1542 | // http://www.w3.org/TR/SVG/implnote.html | ||
1543 | $sinPhi = sin(deg2rad($angle)); | ||
1544 | $cosPhi = cos(deg2rad($angle)); | ||
1545 | |||
1546 | $x1dash = $cosPhi * ($x1-$x2)/2.0 + $sinPhi * ($y1-$y2)/2.0; | ||
1547 | $y1dash = -$sinPhi * ($x1-$x2)/2.0 + $cosPhi * ($y1-$y2)/2.0; | ||
1548 | |||
1549 | |||
1550 | $numerator = $rx*$rx*$ry*$ry - $rx*$rx*$y1dash*$y1dash - $ry*$ry*$x1dash*$x1dash; | ||
1551 | |||
1552 | if ($numerator < 0.0) { | ||
1553 | // If rX , rY and are such that there is no solution (basically, | ||
1554 | // the ellipse is not big enough to reach from (x1, y1) to (x2, | ||
1555 | // y2)) then the ellipse is scaled up uniformly until there is | ||
1556 | // exactly one solution (until the ellipse is just big enough). | ||
1557 | |||
1558 | // -> find factor s, such that numerator' with rx'=s*rx and | ||
1559 | // ry'=s*ry becomes 0 : | ||
1560 | $s = sqrt(1.0 - $numerator/($rx*$rx*$ry*$ry)); | ||
1561 | |||
1562 | $rx *= $s; | ||
1563 | $ry *= $s; | ||
1564 | $root = 0.0; | ||
1565 | |||
1566 | } | ||
1567 | else { | ||
1568 | $root = ($largeArcFlag == $sweepFlag ? -1.0 : 1.0) * sqrt( $numerator/($rx*$rx*$y1dash*$y1dash+$ry*$ry*$x1dash*$x1dash) ); | ||
1569 | } | ||
1570 | |||
1571 | $cxdash = $root*$rx*$y1dash/$ry; | ||
1572 | $cydash = -$root*$ry*$x1dash/$rx; | ||
1573 | |||
1574 | $cx = $cosPhi * $cxdash - $sinPhi * $cydash + ($x1+$x2)/2.0; | ||
1575 | $cy = $sinPhi * $cxdash + $cosPhi * $cydash + ($y1+$y2)/2.0; | ||
1576 | |||
1577 | |||
1578 | $theta1 = $this->CalcVectorAngle(1.0, 0.0, ($x1dash-$cxdash)/$rx, ($y1dash-$cydash)/$ry); | ||
1579 | $dtheta = $this->CalcVectorAngle(($x1dash-$cxdash)/$rx, ($y1dash-$cydash)/$ry, (-$x1dash-$cxdash)/$rx, (-$y1dash-$cydash)/$ry); | ||
1580 | if (!$sweepFlag && $dtheta>0) | ||
1581 | $dtheta -= 2.0*M_PI; | ||
1582 | else if ($sweepFlag && $dtheta<0) | ||
1583 | $dtheta += 2.0*M_PI; | ||
1584 | |||
1585 | // 3. convert into cubic bezier segments <= 90deg | ||
1586 | $segments = ceil(abs($dtheta/(M_PI/2.0))); | ||
1587 | $delta = $dtheta/$segments; | ||
1588 | $t = 8.0/3.0 * sin($delta/4.0) * sin($delta/4.0) / sin($delta/2.0); | ||
1589 | $coords = array(); | ||
1590 | for ($i = 0; $i < $segments; $i++) { | ||
1591 | $cosTheta1 = cos($theta1); | ||
1592 | $sinTheta1 = sin($theta1); | ||
1593 | $theta2 = $theta1 + $delta; | ||
1594 | $cosTheta2 = cos($theta2); | ||
1595 | $sinTheta2 = sin($theta2); | ||
1596 | |||
1597 | // a) calculate endpoint of the segment: | ||
1598 | $xe = $cosPhi * $rx*$cosTheta2 - $sinPhi * $ry*$sinTheta2 + $cx; | ||
1599 | $ye = $sinPhi * $rx*$cosTheta2 + $cosPhi * $ry*$sinTheta2 + $cy; | ||
1600 | |||
1601 | // b) calculate gradients at start/end points of segment: | ||
1602 | $dx1 = $t * ( - $cosPhi * $rx*$sinTheta1 - $sinPhi * $ry*$cosTheta1); | ||
1603 | $dy1 = $t * ( - $sinPhi * $rx*$sinTheta1 + $cosPhi * $ry*$cosTheta1); | ||
1604 | |||
1605 | $dxe = $t * ( $cosPhi * $rx*$sinTheta2 + $sinPhi * $ry*$cosTheta2); | ||
1606 | $dye = $t * ( $sinPhi * $rx*$sinTheta2 - $cosPhi * $ry*$cosTheta2); | ||
1607 | |||
1608 | // c) draw the cubic bezier: | ||
1609 | $coords[$i] = array(($x1+$dx1), ($y1+$dy1), ($xe+$dxe), ($ye+$dye), $xe, $ye); | ||
1610 | |||
1611 | // do next segment | ||
1612 | $theta1 = $theta2; | ||
1613 | $x1 = $xe; | ||
1614 | $y1 = $ye; | ||
1615 | } | ||
1616 | $path = ' '; | ||
1617 | foreach($coords AS $c) { | ||
1618 | $cpx1 = $c[0]; | ||
1619 | $cpy1 = $c[1]; | ||
1620 | $cpx2 = $c[2]; | ||
1621 | $cpy2 = $c[3]; | ||
1622 | $x2 = $c[4]; | ||
1623 | $y2 = $c[5]; | ||
1624 | $path .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $cpx1*$this->kp, -$cpy1*$this->kp, $cpx2*$this->kp, -$cpy2*$this->kp, $x2*$this->kp, -$y2*$this->kp) ."\n"; | ||
1625 | |||
1626 | // mPDF 5.0.040 | ||
1627 | $bounds[0][] = $c[4]; | ||
1628 | $bounds[1][] = $c[5]; | ||
1629 | } | ||
1630 | return array($path, $bounds); // mPD 5.0.040 | ||
1631 | } | ||
1632 | |||
1633 | |||
1634 | function CalcVectorAngle($ux, $uy, $vx, $vy) { | ||
1635 | $ta = atan2($uy, $ux); | ||
1636 | $tb = atan2($vy, $vx); | ||
1637 | if ($tb >= $ta) | ||
1638 | return ($tb-$ta); | ||
1639 | return (6.28318530718 - ($ta-$tb)); | ||
1640 | } | ||
1641 | |||
1642 | |||
1643 | // mPDF 4.4.003 | ||
1644 | function ConvertSVGSizePixels($size=5,$maxsize='x'){ | ||
1645 | // maxsize in pixels (user units) or 'y' or 'x' | ||
1646 | // e.g. $w = $this->ConvertSVGSizePixels($arguments['w'],$this->svg_info['w']*(25.4/$this->mpdf_ref->dpi)); | ||
1647 | // usefontsize - setfalse for e.g. margins - will ignore fontsize for % values | ||
1648 | // Depends of maxsize value to make % work properly. Usually maxsize == pagewidth | ||
1649 | // For text $maxsize = Fontsize | ||
1650 | // Setting e.g. margin % will use maxsize (pagewidth) and em will use fontsize | ||
1651 | |||
1652 | if ($maxsize == 'y') { $maxsize = $this->svg_info['h']; } | ||
1653 | else if ($maxsize == 'x') { $maxsize = $this->svg_info['w']; } | ||
1654 | $maxsize *= (25.4/$this->mpdf_ref->dpi); // convert pixels to mm | ||
1655 | $fontsize=$this->mpdf_ref->FontSize; | ||
1656 | //Return as pixels | ||
1657 | $size = $this->mpdf_ref->ConvertSize($size,$maxsize,$fontsize,false) * 1/(25.4/$this->mpdf_ref->dpi); | ||
1658 | return $size; | ||
1659 | } | ||
1660 | |||
1661 | // mPDF 4.4.003 | ||
1662 | function ConvertSVGSizePts($size=5){ | ||
1663 | // usefontsize - setfalse for e.g. margins - will ignore fontsize for % values | ||
1664 | // Depends of maxsize value to make % work properly. Usually maxsize == pagewidth | ||
1665 | // For text $maxsize = Fontsize | ||
1666 | // Setting e.g. margin % will use maxsize (pagewidth) and em will use fontsize | ||
1667 | $maxsize=$this->mpdf_ref->FontSize; | ||
1668 | //Return as pts | ||
1669 | $size = $this->mpdf_ref->ConvertSize($size,$maxsize,false,true) * 72/25.4; | ||
1670 | return $size; | ||
1671 | } | ||
1672 | |||
1673 | |||
1674 | // | ||
1675 | // fonction retracant les <rect /> | ||
1676 | function svgRect($arguments){ | ||
1677 | |||
1678 | if ($arguments['h']==0 || $arguments['w']==0) { return ''; } // mPDF 4.4.003 | ||
1679 | |||
1680 | $x = $this->ConvertSVGSizePixels($arguments['x'],'x'); // mPDF 4.4.003 | ||
1681 | $y = $this->ConvertSVGSizePixels($arguments['y'],'y'); // mPDF 4.4.003 | ||
1682 | $h = $this->ConvertSVGSizePixels($arguments['h'],'y'); // mPDF 4.4.003 | ||
1683 | $w = $this->ConvertSVGSizePixels($arguments['w'],'x'); // mPDF 4.4.003 | ||
1684 | $rx = $this->ConvertSVGSizePixels($arguments['rx'],'x'); // mPDF 4.4.003 | ||
1685 | $ry = $this->ConvertSVGSizePixels($arguments['ry'],'y'); // mPDF 4.4.003 | ||
1686 | |||
1687 | if ($rx > $w/2) { $rx = $w/2; } // mPDF 4.4.003 | ||
1688 | if ($ry > $h/2) { $ry = $h/2; } // mPDF 4.4.003 | ||
1689 | |||
1690 | if ($rx>0 and $ry == 0){$ry = $rx;} | ||
1691 | if ($ry>0 and $rx == 0){$rx = $ry;} | ||
1692 | |||
1693 | if ($rx == 0 and $ry == 0){ | ||
1694 | // trace un rectangle sans angle arrondit | ||
1695 | $path_cmd = sprintf('%.3F %.3F m ', ($x*$this->kp), -($y*$this->kp)); | ||
1696 | $path_cmd .= sprintf('%.3F %.3F l ', (($x+$w)*$this->kp), -($y*$this->kp)); | ||
1697 | $path_cmd .= sprintf('%.3F %.3F l ', (($x+$w)*$this->kp), -(($y+$h)*$this->kp)); | ||
1698 | $path_cmd .= sprintf('%.3F %.3F l ', ($x)*$this->kp, -(($y+$h)*$this->kp)); | ||
1699 | $path_cmd .= sprintf('%.3F %.3F l h ', ($x*$this->kp), -($y*$this->kp)); | ||
1700 | |||
1701 | |||
1702 | } | ||
1703 | else { | ||
1704 | // trace un rectangle avec les arrondit | ||
1705 | // les points de controle du bezier sont deduis grace a la constante kappa | ||
1706 | $kappa = 4*(sqrt(2)-1)/3; | ||
1707 | |||
1708 | $kx = $kappa*$rx; | ||
1709 | $ky = $kappa*$ry; | ||
1710 | |||
1711 | $path_cmd = sprintf('%.3F %.3F m ', ($x+$rx)*$this->kp, -$y*$this->kp); | ||
1712 | $path_cmd .= sprintf('%.3F %.3F l ', ($x+($w-$rx))*$this->kp, -$y*$this->kp); | ||
1713 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($x+($w-$rx+$kx))*$this->kp, -$y*$this->kp, ($x+$w)*$this->kp, (-$y+(-$ry+$ky))*$this->kp, ($x+$w)*$this->kp, (-$y+(-$ry))*$this->kp ); | ||
1714 | $path_cmd .= sprintf('%.3F %.3F l ', ($x+$w)*$this->kp, (-$y+(-$h+$ry))*$this->kp); | ||
1715 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($x+$w)*$this->kp, (-$y+(-$h-$ky+$ry))*$this->kp, ($x+($w-$rx+$kx))*$this->kp, (-$y+(-$h))*$this->kp, ($x+($w-$rx))*$this->kp, (-$y+(-$h))*$this->kp ); | ||
1716 | |||
1717 | $path_cmd .= sprintf('%.3F %.3F l ', ($x+$rx)*$this->kp, (-$y+(-$h))*$this->kp); | ||
1718 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($x+($rx-$kx))*$this->kp, (-$y+(-$h))*$this->kp, $x*$this->kp, (-$y+(-$h-$ky+$ry))*$this->kp, $x*$this->kp, (-$y+(-$h+$ry))*$this->kp ); | ||
1719 | $path_cmd .= sprintf('%.3F %.3F l ', $x*$this->kp, (-$y+(-$ry))*$this->kp); | ||
1720 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c h ', $x*$this->kp, (-$y+(-$ry+$ky))*$this->kp, ($x+($rx-$kx))*$this->kp, -$y*$this->kp, ($x+$rx)*$this->kp, -$y*$this->kp ); | ||
1721 | |||
1722 | |||
1723 | } | ||
1724 | return $path_cmd; | ||
1725 | } | ||
1726 | |||
1727 | // | ||
1728 | // fonction retracant les <ellipse /> et <circle /> | ||
1729 | // le cercle est tracé grave a 4 bezier cubic, les poitn de controles | ||
1730 | // sont deduis grace a la constante kappa * rayon | ||
1731 | function svgEllipse($arguments){ | ||
1732 | if ($arguments['rx']==0 || $arguments['ry']==0) { return ''; } // mPDF 4.4.003 | ||
1733 | |||
1734 | $kappa = 4*(sqrt(2)-1)/3; | ||
1735 | |||
1736 | $cx = $this->ConvertSVGSizePixels($arguments['cx'],'x'); // mPDF 4.4.003 | ||
1737 | $cy = $this->ConvertSVGSizePixels($arguments['cy'],'y'); // mPDF 4.4.003 | ||
1738 | $rx = $this->ConvertSVGSizePixels($arguments['rx'],'x'); // mPDF 4.4.003 | ||
1739 | $ry = $this->ConvertSVGSizePixels($arguments['ry'],'y'); // mPDF 4.4.003 | ||
1740 | |||
1741 | $x1 = $cx; | ||
1742 | $y1 = -$cy+$ry; | ||
1743 | |||
1744 | $x2 = $cx+$rx; | ||
1745 | $y2 = -$cy; | ||
1746 | |||
1747 | $x3 = $cx; | ||
1748 | $y3 = -$cy-$ry; | ||
1749 | |||
1750 | $x4 = $cx-$rx; | ||
1751 | $y4 = -$cy; | ||
1752 | |||
1753 | $path_cmd = sprintf('%.3F %.3F m ', $x1*$this->kp, $y1*$this->kp); | ||
1754 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($x1+($rx*$kappa))*$this->kp, $y1*$this->kp, $x2*$this->kp, ($y2+($ry*$kappa))*$this->kp, $x2*$this->kp, $y2*$this->kp); | ||
1755 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $x2*$this->kp, ($y2-($ry*$kappa))*$this->kp, ($x3+($rx*$kappa))*$this->kp, $y3*$this->kp, $x3*$this->kp, $y3*$this->kp); | ||
1756 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($x3-($rx*$kappa))*$this->kp, $y3*$this->kp, $x4*$this->kp, ($y4-($ry*$kappa))*$this->kp, $x4*$this->kp, $y4*$this->kp); | ||
1757 | $path_cmd .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $x4*$this->kp, ($y4+($ry*$kappa))*$this->kp, ($x1-($rx*$kappa))*$this->kp, $y1*$this->kp, $x1*$this->kp, $y1*$this->kp); | ||
1758 | $path_cmd .= 'h '; | ||
1759 | |||
1760 | return $path_cmd; | ||
1761 | |||
1762 | } | ||
1763 | |||
1764 | // | ||
1765 | // fonction retracant les <polyline /> et les <line /> | ||
1766 | function svgPolyline($arguments,$ispolyline=true){ | ||
1767 | if ($ispolyline) { | ||
1768 | $xbase = $arguments[0] ; | ||
1769 | $ybase = - $arguments[1] ; | ||
1770 | } | ||
1771 | else { | ||
1772 | if ($arguments[0]==$arguments[2] && $arguments[1]==$arguments[3]) { return ''; } // mPDF 4.4.003 Zero length line | ||
1773 | $xbase = $this->ConvertSVGSizePixels($arguments[0],'x'); // mPDF 4.4.003 | ||
1774 | $ybase = - $this->ConvertSVGSizePixels($arguments[1],'y'); // mPDF 4.4.003 | ||
1775 | } | ||
1776 | $path_cmd = sprintf('%.3F %.3F m ', $xbase*$this->kp, $ybase*$this->kp); | ||
1777 | for ($i = 2; $i<count($arguments);$i += 2) { | ||
1778 | if ($ispolyline) { | ||
1779 | $tmp_x = $arguments[$i] ; | ||
1780 | $tmp_y = - $arguments[($i+1)] ; | ||
1781 | } | ||
1782 | else { | ||
1783 | $tmp_x = $this->ConvertSVGSizePixels($arguments[$i],'x') ; // mPDF 4.4.003 | ||
1784 | $tmp_y = - $this->ConvertSVGSizePixels($arguments[($i+1)],'y') ; // mPDF 4.4.003 | ||
1785 | } | ||
1786 | $path_cmd .= sprintf('%.3F %.3F l ', $tmp_x*$this->kp, $tmp_y*$this->kp); | ||
1787 | } | ||
1788 | |||
1789 | // $path_cmd .= 'h '; // ?? In error - don't close subpath here | ||
1790 | return $path_cmd; | ||
1791 | |||
1792 | } | ||
1793 | |||
1794 | // | ||
1795 | // fonction retracant les <polygone /> | ||
1796 | function svgPolygon($arguments){ | ||
1797 | $xbase = $arguments[0] ; | ||
1798 | $ybase = - $arguments[1] ; | ||
1799 | $path_cmd = sprintf('%.3F %.3F m ', $xbase*$this->kp, $ybase*$this->kp); | ||
1800 | for ($i = 2; $i<count($arguments);$i += 2) { | ||
1801 | $tmp_x = $arguments[$i] ; | ||
1802 | $tmp_y = - $arguments[($i+1)] ; | ||
1803 | |||
1804 | $path_cmd .= sprintf('%.3F %.3F l ', $tmp_x*$this->kp, $tmp_y*$this->kp); | ||
1805 | |||
1806 | } | ||
1807 | $path_cmd .= sprintf('%.3F %.3F l ', $xbase*$this->kp, $ybase*$this->kp); | ||
1808 | $path_cmd .= 'h '; | ||
1809 | return $path_cmd; | ||
1810 | |||
1811 | } | ||
1812 | |||
1813 | // | ||
1814 | // write string to image | ||
1815 | function svgText() { | ||
1816 | // $tmp = count($this->txt_style)-1; | ||
1817 | $current_style = array_pop($this->txt_style); | ||
1818 | $style = ''; | ||
1819 | $render = -1; | ||
1820 | if(isset($this->txt_data[2])) | ||
1821 | { | ||
1822 | // select font | ||
1823 | $style .= ($current_style['font-weight'] == 'bold')?'B':''; | ||
1824 | $style .= ($current_style['font-style'] == 'italic')?'I':''; | ||
1825 | $size = $current_style['font-size']*$this->kf; // mPDF 5.0.039 | ||
1826 | |||
1827 | // mPDF 5.0 | ||
1828 | $current_style['font-family'] = $this->mpdf_ref->SetFont($current_style['font-family'],$style,$size,false); | ||
1829 | $this->mpdf_ref->CurrentFont['fo'] = true; // mPDF 5.0.039 | ||
1830 | |||
1831 | |||
1832 | // mPDF 5.0.041 | ||
1833 | $opacitystr = ''; | ||
1834 | $opacity = 1; | ||
1835 | if (isset($current_style['fill-opacity'])) { | ||
1836 | if ($current_style['fill-opacity'] == 0) { $opacity = 0; } | ||
1837 | else if ($current_style['fill-opacity'] > 1) { $opacity = 1; } | ||
1838 | else if ($current_style['fill-opacity'] > 0) { $opacity = $current_style['fill-opacity']; } | ||
1839 | else if ($current_style['fill-opacity'] < 0) { $opacity = 0; } | ||
1840 | } | ||
1841 | $gs = $this->mpdf_ref->AddExtGState(array('ca'=>$opacity, 'BM'=>'/Normal')); | ||
1842 | $this->mpdf_ref->extgstates[$gs]['fo'] = true; // mPDF 5.0.039 | ||
1843 | $opacitystr = sprintf(' /GS%d gs ', $gs); | ||
1844 | |||
1845 | // mPDF 5.0.051 | ||
1846 | $fillstr = ''; | ||
1847 | if (isset($current_style['fill']) && $current_style['fill']!='none') { | ||
1848 | $col = $this->mpdf_ref->ConvertColor($current_style['fill']); | ||
1849 | // mPDF 5.0.051 | ||
1850 | $fillstr = $this->mpdf_ref->SetFColor($col, true); | ||
1851 | $render = "0"; // Fill (only) | ||
1852 | } | ||
1853 | $strokestr = ''; | ||
1854 | if (isset($current_style['stroke-width']) && $current_style['stroke-width']>0 && $current_style['stroke']!='none') { | ||
1855 | $scol = $this->mpdf_ref->ConvertColor($current_style['stroke']); | ||
1856 | if ($scol) { | ||
1857 | $strokestr .= $this->mpdf_ref->SetDColor($scol, true).' '; // mPDF 5.0.051 | ||
1858 | } | ||
1859 | $linewidth = $this->ConvertSVGSizePixels($current_style['stroke-width']); | ||
1860 | if ($linewidth > 0) { | ||
1861 | $strokestr .= sprintf('%.3F w 1 J 1 j ',$linewidth*$this->kp); | ||
1862 | if ($render == -1) { $render = "1"; } // stroke only | ||
1863 | else { $render = "2"; } // fill and stroke | ||
1864 | } | ||
1865 | } | ||
1866 | if ($render == -1) { return ''; } | ||
1867 | |||
1868 | $x = $this->ConvertSVGSizePixels($this->txt_data[0],'x'); // mPDF 4.4.003 | ||
1869 | $y = $this->ConvertSVGSizePixels($this->txt_data[1],'y'); // mPDF 4.4.003 | ||
1870 | $txt = $this->txt_data[2]; | ||
1871 | |||
1872 | // mPDF 4.4.003 | ||
1873 | $txt = preg_replace('/\f/','',$txt); | ||
1874 | $txt = preg_replace('/\r/','',$txt); | ||
1875 | $txt = preg_replace('/\n/',' ',$txt); | ||
1876 | $txt = preg_replace('/\t/',' ',$txt); | ||
1877 | $txt = preg_replace("/[ ]+/u",' ',$txt); | ||
1878 | |||
1879 | $txt = trim($txt); | ||
1880 | |||
1881 | $txt = $this->mpdf_ref->purify_utf8_text($txt); | ||
1882 | if ($this->mpdf_ref->text_input_as_HTML) { | ||
1883 | $txt = $this->mpdf_ref->all_entities_to_utf8($txt); | ||
1884 | } | ||
1885 | |||
1886 | // mPDF 5.0 | ||
1887 | if ($this->mpdf_ref->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mpdf_ref->mb_enc,'UTF-8'); } | ||
1888 | if (preg_match("/([".$this->mpdf_ref->pregRTLchars."])/u", $txt)) { $this->mpdf_ref->biDirectional = true; } // mPDF 4.4.003 | ||
1889 | |||
1890 | $this->mpdf_ref->magic_reverse_dir($txt, true, 'ltr'); // mPDF 5.0.054 | ||
1891 | $this->mpdf_ref->ConvertIndic($txt); | ||
1892 | |||
1893 | |||
1894 | if ($current_style['text-anchor']=='middle') { | ||
1895 | $tw = $this->mpdf_ref->GetStringWidth($txt)*_MPDFK/2; // mPDF 4.4.003 // mPDF 5.4.09 | ||
1896 | } | ||
1897 | else if ($current_style['text-anchor']=='end') { | ||
1898 | $tw = $this->mpdf_ref->GetStringWidth($txt)*_MPDFK; // mPDF 4.4.003 // mPDF 5.4.09 | ||
1899 | } | ||
1900 | else $tw = 0; | ||
1901 | |||
1902 | if (!$this->mpdf_ref->usingCoreFont) { | ||
1903 | $this->mpdf_ref->UTF8StringToArray($txt); // mPDF 5.0 adds chars to subset list | ||
1904 | $txt= $this->mpdf_ref->UTF8ToUTF16BE($txt, false); | ||
1905 | } | ||
1906 | $txt='('.$this->mpdf_ref->_escape($txt).')'; | ||
1907 | $this->mpdf_ref->CurrentFont['used']= true; | ||
1908 | |||
1909 | $pdfx = $x - $tw/$this->kp; // mPDF 4.4.009 | ||
1910 | $pdfy = -$y ; | ||
1911 | $xbase = $x; | ||
1912 | $ybase = -$y; | ||
1913 | |||
1914 | // mPDF 5.7.2 | ||
1915 | $path_cmd = sprintf('q BT /F%d %.3F Tf %s %.3F %.3F Td %s Tr %s %s %s Tj ET Q ',$this->mpdf_ref->CurrentFont['i'], $this->mpdf_ref->FontSizePt, $opacitystr, $pdfx*$this->kp,$pdfy*$this->kp,$render,$fillstr,$strokestr,$txt)."\n"; | ||
1916 | unset($this->txt_data[0], $this->txt_data[1],$this->txt_data[2]); | ||
1917 | |||
1918 | if (isset($current_style['font-size-parent'])) { | ||
1919 | $this->mpdf_ref->SetFontSize($current_style['font-size-parent']); | ||
1920 | } | ||
1921 | } | ||
1922 | else | ||
1923 | { | ||
1924 | return ' '; | ||
1925 | } | ||
1926 | return $path_cmd; | ||
1927 | } | ||
1928 | |||
1929 | |||
1930 | function svgDefineTxtStyle($critere_style) | ||
1931 | { | ||
1932 | // get copy of current/default txt style, and modify it with supplied attributes | ||
1933 | $tmp = count($this->txt_style)-1; | ||
1934 | $current_style = $this->txt_style[$tmp]; | ||
1935 | if (isset($critere_style['style'])){ | ||
1936 | if (preg_match('/fill:\s*rgb\((\d+),\s*(\d+),\s*(\d+)\)/',$critere_style['style'], $m)) { | ||
1937 | $current_style['fill'] = '#'.str_pad(dechex($m[1]), 2, "0", STR_PAD_LEFT).str_pad(dechex($m[2]), 2, "0", STR_PAD_LEFT).str_pad(dechex($m[3]), 2, "0", STR_PAD_LEFT); | ||
1938 | } | ||
1939 | else { $tmp = preg_replace("/(.*)fill:\s*([a-z0-9#_()]*|none)(.*)/i","$2",$critere_style['style']); | ||
1940 | if ($tmp != $critere_style['style']){ $current_style['fill'] = $tmp; } | ||
1941 | } | ||
1942 | |||
1943 | $tmp = preg_replace("/(.*)fill-opacity:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
1944 | if ($tmp != $critere_style['style']){ $current_style['fill-opacity'] = $tmp;} | ||
1945 | |||
1946 | $tmp = preg_replace("/(.*)fill-rule:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
1947 | if ($tmp != $critere_style['style']){ $current_style['fill-rule'] = $tmp;} | ||
1948 | |||
1949 | if (preg_match('/stroke:\s*rgb\((\d+),\s*(\d+),\s*(\d+)\)/',$critere_style['style'], $m)) { | ||
1950 | $current_style['stroke'] = '#'.str_pad(dechex($m[1]), 2, "0", STR_PAD_LEFT).str_pad(dechex($m[2]), 2, "0", STR_PAD_LEFT).str_pad(dechex($m[3]), 2, "0", STR_PAD_LEFT); | ||
1951 | } | ||
1952 | else { $tmp = preg_replace("/(.*)stroke:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
1953 | if ($tmp != $critere_style['style']){ $current_style['stroke'] = $tmp; } | ||
1954 | } | ||
1955 | |||
1956 | $tmp = preg_replace("/(.*)stroke-linecap:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
1957 | if ($tmp != $critere_style['style']){ $current_style['stroke-linecap'] = $tmp;} | ||
1958 | |||
1959 | $tmp = preg_replace("/(.*)stroke-linejoin:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
1960 | if ($tmp != $critere_style['style']){ $current_style['stroke-linejoin'] = $tmp;} | ||
1961 | |||
1962 | $tmp = preg_replace("/(.*)stroke-miterlimit:\s*([a-z0-9#]*|none)(.*)/i","$2",$critere_style['style']); | ||
1963 | if ($tmp != $critere_style['style']){ $current_style['stroke-miterlimit'] = $tmp;} | ||
1964 | |||
1965 | $tmp = preg_replace("/(.*)stroke-opacity:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
1966 | if ($tmp != $critere_style['style']){ $current_style['stroke-opacity'] = $tmp; } | ||
1967 | |||
1968 | $tmp = preg_replace("/(.*)stroke-width:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
1969 | if ($tmp != $critere_style['style']){ $current_style['stroke-width'] = $tmp;} | ||
1970 | |||
1971 | $tmp = preg_replace("/(.*)stroke-dasharray:\s*([a-z0-9., ]*|none)(.*)/i","$2",$critere_style['style']); | ||
1972 | if ($tmp != $critere_style['style']){ $current_style['stroke-dasharray'] = $tmp;} | ||
1973 | |||
1974 | $tmp = preg_replace("/(.*)stroke-dashoffset:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
1975 | if ($tmp != $critere_style['style']){ $current_style['stroke-dashoffset'] = $tmp;} | ||
1976 | |||
1977 | // mPDF 5.7.2 | ||
1978 | $tmp = preg_replace("/(.*)font-family:\s*([a-z0-9.\"' ,\-]*|none)(.*)/i","$2",$critere_style['style']); | ||
1979 | if ($tmp != $critere_style['style']){ $critere_style['font-family'] = $tmp;} | ||
1980 | |||
1981 | $tmp = preg_replace("/(.*)font-size:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
1982 | if ($tmp != $critere_style['style']){ $critere_style['font-size'] = $tmp;} | ||
1983 | |||
1984 | $tmp = preg_replace("/(.*)font-weight:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
1985 | if ($tmp != $critere_style['style']){ $critere_style['font-weight'] = $tmp;} | ||
1986 | |||
1987 | $tmp = preg_replace("/(.*)font-style:\s*([a-z0-9.]*|none)(.*)/i","$2",$critere_style['style']); | ||
1988 | if ($tmp != $critere_style['style']){ $critere_style['font-style'] = $tmp;} | ||
1989 | |||
1990 | } | ||
1991 | |||
1992 | if (isset($critere_style['font'])){ | ||
1993 | |||
1994 | // [ [ <'font-style'> || <'font-variant'> || <'font-weight'> ]?<'font-size'> [ / <'line-height'> ]? <'font-family'> ] | ||
1995 | |||
1996 | $tmp = preg_replace("/(.*)(italic|oblique)(.*)/i","$2",$critere_style['font']); | ||
1997 | if ($tmp != $critere_style['font']){ | ||
1998 | if($tmp == 'oblique'){ | ||
1999 | $tmp = 'italic'; | ||
2000 | } | ||
2001 | $current_style['font-style'] = $tmp; | ||
2002 | } | ||
2003 | $tmp = preg_replace("/(.*)(bold|bolder)(.*)/i","$2",$critere_style['font']); | ||
2004 | if ($tmp != $critere_style['font']){ | ||
2005 | if($tmp == 'bolder'){ | ||
2006 | $tmp = 'bold'; | ||
2007 | } | ||
2008 | $current_style['font-weight'] = $tmp; | ||
2009 | } | ||
2010 | |||
2011 | // select digits not followed by percent sign nor preceeded by forward slash | ||
2012 | $tmp = preg_replace("/(.*)\b(\d+)[\b|\/](.*)/i","$2",$critere_style['font']); | ||
2013 | if ($tmp != $critere_style['font']){ | ||
2014 | $current_style['font-size'] = $this->ConvertSVGSizePts($tmp); | ||
2015 | $this->mpdf_ref->SetFont('','',$current_style['font-size'],false); | ||
2016 | } | ||
2017 | |||
2018 | } | ||
2019 | |||
2020 | if(isset($critere_style['fill'])){ | ||
2021 | $current_style['fill'] = $critere_style['fill']; | ||
2022 | } | ||
2023 | if(isset($critere_style['stroke'])){ | ||
2024 | $current_style['stroke'] = $critere_style['stroke']; | ||
2025 | } | ||
2026 | if(isset($critere_style['stroke-width'])){ | ||
2027 | $current_style['stroke-width'] = $critere_style['stroke-width']; | ||
2028 | } | ||
2029 | |||
2030 | if(isset($critere_style['font-style'])){ | ||
2031 | if(strtolower($critere_style['font-style']) == 'oblique') | ||
2032 | { | ||
2033 | $critere_style['font-style'] = 'italic'; | ||
2034 | } | ||
2035 | $current_style['font-style'] = $critere_style['font-style']; | ||
2036 | } | ||
2037 | |||
2038 | if(isset($critere_style['font-weight'])){ | ||
2039 | if(strtolower($critere_style['font-weight']) == 'bolder') | ||
2040 | { | ||
2041 | $critere_style['font-weight'] = 'bold'; | ||
2042 | } | ||
2043 | $current_style['font-weight'] = $critere_style['font-weight']; | ||
2044 | } | ||
2045 | |||
2046 | if(isset($critere_style['font-size'])){ | ||
2047 | // mPDF 5.4.12 | ||
2048 | if (strpos($critere_style['font-size'], '%')!==false) { | ||
2049 | $current_style['font-size-parent'] = $current_style['font-size']; | ||
2050 | } | ||
2051 | $current_style['font-size'] = $this->ConvertSVGSizePts($critere_style['font-size']); | ||
2052 | $this->mpdf_ref->SetFont('','',$current_style['font-size'],false); | ||
2053 | } | ||
2054 | |||
2055 | if(isset($critere_style['font-family'])){ | ||
2056 | $v = $critere_style['font-family']; | ||
2057 | $aux_fontlist = explode(",",$v); | ||
2058 | $found = 0; | ||
2059 | foreach($aux_fontlist AS $f) { | ||
2060 | $fonttype = trim($f); | ||
2061 | $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype); | ||
2062 | $fonttype = preg_replace('/ /','',$fonttype); | ||
2063 | $v = strtolower(trim($fonttype)); | ||
2064 | if (isset($this->mpdf_ref->fonttrans[$v]) && $this->mpdf_ref->fonttrans[$v]) { $v = $this->mpdf_ref->fonttrans[$v]; } | ||
2065 | if ((!$this->mpdf_ref->usingCoreFont && in_array($v,$this->mpdf_ref->available_unifonts)) || | ||
2066 | ($this->mpdf_ref->usingCoreFont && in_array($v,array('courier','times','helvetica','arial'))) || | ||
2067 | in_array($v, array('sjis','uhc','big5','gb'))) { | ||
2068 | $current_style['font-family'] = $v; | ||
2069 | $found = 1; | ||
2070 | break; | ||
2071 | } | ||
2072 | } | ||
2073 | if (!$found) { | ||
2074 | foreach($aux_fontlist AS $f) { | ||
2075 | $fonttype = trim($f); | ||
2076 | $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype); | ||
2077 | $fonttype = preg_replace('/ /','',$fonttype); | ||
2078 | $v = strtolower(trim($fonttype)); | ||
2079 | if (isset($this->mpdf_ref->fonttrans[$v]) && $this->mpdf_ref->fonttrans[$v]) { $v = $this->mpdf_ref->fonttrans[$v]; } | ||
2080 | if (in_array($v,$this->mpdf_ref->sans_fonts) || in_array($v,$this->mpdf_ref->serif_fonts) || in_array($v,$this->mpdf_ref->mono_fonts) ) { | ||
2081 | $current_style['font-family'] = $v; | ||
2082 | break; | ||
2083 | } | ||
2084 | } | ||
2085 | } | ||
2086 | } | ||
2087 | |||
2088 | if(isset($critere_style['text-anchor'])){ | ||
2089 | $current_style['text-anchor'] = $critere_style['text-anchor']; | ||
2090 | } | ||
2091 | |||
2092 | // add current style to text style array (will remove it later after writing text to svg_string) | ||
2093 | array_push($this->txt_style,$current_style); | ||
2094 | } | ||
2095 | |||
2096 | |||
2097 | |||
2098 | // | ||
2099 | // fonction ajoutant un gradient | ||
2100 | function svgAddGradient($id,$array_gradient){ | ||
2101 | |||
2102 | $this->svg_gradient[$id] = $array_gradient; | ||
2103 | |||
2104 | } | ||
2105 | // | ||
2106 | // Ajoute une couleur dans le gradient correspondant | ||
2107 | |||
2108 | // | ||
2109 | // function ecrivant dans le svgstring | ||
2110 | function svgWriteString($content){ | ||
2111 | |||
2112 | $this->svg_string .= $content; | ||
2113 | |||
2114 | } | ||
2115 | |||
2116 | |||
2117 | |||
2118 | // analise le svg et renvoie aux fonctions precedente our le traitement | ||
2119 | function ImageSVG($data){ | ||
2120 | $this->svg_info = array(); | ||
2121 | |||
2122 | // mPDF 4.4.006 | ||
2123 | if (preg_match('/<!ENTITY/si',$data)) { | ||
2124 | // Get User-defined entities | ||
2125 | preg_match_all('/<!ENTITY\s+([a-z]+)\s+\"(.*?)\">/si',$data, $ent); | ||
2126 | // Replace entities | ||
2127 | for ($i=0; $i<count($ent[0]); $i++) { | ||
2128 | $data = preg_replace('/&'.preg_quote($ent[1][$i],'/').';/is', $ent[2][$i], $data); | ||
2129 | } | ||
2130 | } | ||
2131 | |||
2132 | |||
2133 | if (preg_match('/xlink:href=/si',$data)) { | ||
2134 | // GRADIENTS | ||
2135 | // Get links | ||
2136 | preg_match_all('/(<(linearGradient|radialgradient)[^>]*)xlink:href=["\']#(.*?)["\'](.*?)\/>/si',$data, $links); | ||
2137 | if (count($links[0])) { $links[5] = array(); } | ||
2138 | // Delete links from data - keeping in $links | ||
2139 | for ($i=0; $i<count($links[0]); $i++) { | ||
2140 | $links[5][$i] = 'tmpLink'.RAND(100000,9999999); | ||
2141 | $data = preg_replace('/'.preg_quote($links[0][$i],'/').'/is', '<MYLINKS'.$links[5][$i].'>' , $data); | ||
2142 | } | ||
2143 | // Get targets | ||
2144 | preg_match_all('/<(linearGradient|radialgradient)([^>]*)id=["\'](.*?)["\'](.*?)>(.*?)<\/(linearGradient|radialgradient)>/si',$data, $m); | ||
2145 | $targets = array(); | ||
2146 | $stops = array(); | ||
2147 | // keeping in $targets | ||
2148 | for ($i=0; $i<count($m[0]); $i++) { | ||
2149 | $stops[$m[3][$i]] = $m[5][$i]; | ||
2150 | } | ||
2151 | // Add back links this time as targets (gradients) | ||
2152 | for ($i=0; $i<count($links[0]); $i++) { | ||
2153 | $def = $links[1][$i] .' '.$links[4][$i].'>'. $stops[$links[3][$i]].'</'.$links[2][$i] .'>' ; | ||
2154 | $data = preg_replace('/<MYLINKS'.$links[5][$i].'>/is', $def , $data); | ||
2155 | } | ||
2156 | |||
2157 | // mPDF 5.7.2 | ||
2158 | // <USE> | ||
2159 | preg_match_all('/<use ([^>]*)xlink:href=["\']#([^>]*?)["\']([^>]*)\/>/si',$data, $links); | ||
2160 | for ($i=0; $i<count($links[0]); $i++) { | ||
2161 | |||
2162 | // Get the item to use from defs | ||
2163 | $insert = ''; | ||
2164 | if (preg_match('/<([a-zA-Z]*) [^>]*id=["\']'.$links[2][$i].'["\'][^>]*\/>/si',$data, $m)) { | ||
2165 | $insert = $m[0]; | ||
2166 | } | ||
2167 | if (!$insert && preg_match('/<([a-zA-Z]*) [^>]*id=["\']'.$links[2][$i].'["\']/si',$data, $m)) { | ||
2168 | |||
2169 | if (preg_match('/<'.$m[1].'[^>]*id=["\']'.$links[2][$i].'["\'][^>]*>.*?<\/'.$m[1].'>/si',$data, $m)) { | ||
2170 | $insert = $m[0]; | ||
2171 | } | ||
2172 | } | ||
2173 | |||
2174 | if ($insert) { | ||
2175 | |||
2176 | $inners = $links[1][$i] . ' ' . $links[3][$i]; | ||
2177 | // Change x,y coords to translate() | ||
2178 | if (preg_match('/y=["\']([^>]*?)["\']/', $inners, $m)) { $y = $m[1]; } | ||
2179 | else { $y = 0; } | ||
2180 | if (preg_match('/x=["\']([^>]*?)["\']/', $inners, $m)) { $x = $m[1]; } | ||
2181 | else { $x = 0; } | ||
2182 | if ($x || $y) { | ||
2183 | $inners = preg_replace('/(y|x)=["\']([^>]*?)["\']/', '', $inners); | ||
2184 | if (preg_match('/transform=["\']([^>]*?)["\']/', $inners, $m)) { | ||
2185 | if (preg_match('/translate\(\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*\)/', $m[1], $mm)) { | ||
2186 | $transform = $m[1]; // transform="...." | ||
2187 | $x += $mm[1]; | ||
2188 | $y += $mm[2]; | ||
2189 | $transform = preg_replace('/'.preg_quote($mm[0],'/').'/', '', $transform); | ||
2190 | $transform = 'transform="'.$transform.' translate('.$x.', '.$y.')"'; | ||
2191 | $inners = preg_replace('/'.preg_quote($m[0],'/').'/is', $transform, $inners); | ||
2192 | } | ||
2193 | else { | ||
2194 | $inners = preg_replace('/'.preg_quote($m[0],'/').'/is', 'transform="'.$m[1].' translate('.$x.', '.$y.')"', $inners); | ||
2195 | } | ||
2196 | } | ||
2197 | else { | ||
2198 | $inners .= ' transform="translate('.$x.', '.$y.')"'; | ||
2199 | } | ||
2200 | } | ||
2201 | } | ||
2202 | $replacement = '<g '.$inners.'>'.$insert.'</g>'; | ||
2203 | $data = preg_replace('/'.preg_quote($links[0][$i],'/').'/is', $replacement, $data); | ||
2204 | } | ||
2205 | preg_match_all('/<use ([^>]*)xlink:href=["\']#([^>]*?)["\']([^>]*)>\s*<\/use>/si',$data, $links); | ||
2206 | for ($i=0; $i<count($links[0]); $i++) { | ||
2207 | |||
2208 | // Get the item to use from defs | ||
2209 | $insert = ''; | ||
2210 | if (preg_match('/<([a-zA-Z]*) [^>]*id=["\']'.$links[2][$i].'["\'][^>]*\/>/si',$data, $m)) { | ||
2211 | $insert = $m[0]; | ||
2212 | } | ||
2213 | if (!$insert && preg_match('/<([a-zA-Z]*) [^>]*id=["\']'.$links[2][$i].'["\']/si',$data, $m)) { | ||
2214 | |||
2215 | if (preg_match('/<'.$m[1].'[^>]*id=["\']'.$links[2][$i].'["\'][^>]*>.*?<\/'.$m[1].'>/si',$data, $m)) { | ||
2216 | $insert = $m[0]; | ||
2217 | } | ||
2218 | } | ||
2219 | |||
2220 | if ($insert) { | ||
2221 | |||
2222 | $inners = $links[1][$i] . ' ' . $links[3][$i]; | ||
2223 | // Change x,y coords to translate() | ||
2224 | if (preg_match('/y=["\']([^>]*?)["\']/', $inners, $m)) { $y = $m[1]; } | ||
2225 | else { $y = 0; } | ||
2226 | if (preg_match('/x=["\']([^>]*?)["\']/', $inners, $m)) { $x = $m[1]; } | ||
2227 | else { $x = 0; } | ||
2228 | if ($x || $y) { | ||
2229 | $inners = preg_replace('/(y|x)=["\']([^>]*?)["\']/', '', $inners); | ||
2230 | if (preg_match('/transform=["\']([^>]*?)["\']/', $inners, $m)) { | ||
2231 | if (preg_match('/translate\(\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*\)/', $m[1], $mm)) { | ||
2232 | $transform = $m[1]; // transform="...." | ||
2233 | $x += $mm[1]; | ||
2234 | $y += $mm[2]; | ||
2235 | $transform = preg_replace('/'.preg_quote($mm[0],'/').'/', '', $transform); | ||
2236 | $transform = 'transform="'.$transform.' translate('.$x.', '.$y.')"'; | ||
2237 | $inners = preg_replace('/'.preg_quote($m[0],'/').'/is', $transform, $inners); | ||
2238 | } | ||
2239 | else { | ||
2240 | $inners = preg_replace('/'.preg_quote($m[0],'/').'/is', 'transform="'.$m[1].' translate('.$x.', '.$y.')"', $inners); | ||
2241 | } | ||
2242 | } | ||
2243 | else { | ||
2244 | $inners .= ' transform="translate('.$x.', '.$y.')"'; | ||
2245 | } | ||
2246 | } | ||
2247 | $replacement = '<g '.$inners.'>'.$insert.'</g>'; | ||
2248 | $data = preg_replace('/'.preg_quote($links[0][$i],'/').'/is', $replacement, $data); | ||
2249 | |||
2250 | |||
2251 | } | ||
2252 | } | ||
2253 | } | ||
2254 | // Removes <pattern> | ||
2255 | $data = preg_replace('/<pattern.*?<\/pattern>/is', '', $data); | ||
2256 | // Removes <marker> | ||
2257 | $data = preg_replace('/<marker.*?<\/marker>/is', '', $data); | ||
2258 | |||
2259 | $this->svg_info['data'] = $data; | ||
2260 | |||
2261 | $this->svg_string = ''; | ||
2262 | |||
2263 | // | ||
2264 | // chargement unique des fonctions | ||
2265 | if(!function_exists("xml_svg2pdf_start")){ | ||
2266 | |||
2267 | function xml_svg2pdf_start($parser, $name, $attribs){ | ||
2268 | // | ||
2269 | // definition | ||
2270 | global $svg_class, $last_gradid; | ||
2271 | |||
2272 | // mPDF 5.7.2 | ||
2273 | if (strtolower($name) == 'lineargradient'){ | ||
2274 | $tmp_gradient = array( | ||
2275 | 'type' => 'linear', | ||
2276 | 'info' => array( | ||
2277 | 'x1' => $attribs['x1'], | ||
2278 | 'y1' => $attribs['y1'], | ||
2279 | 'x2' => $attribs['x2'], | ||
2280 | 'y2' => $attribs['y2'] | ||
2281 | ), | ||
2282 | 'transform' => $attribs['gradientTransform'], | ||
2283 | 'units' => $attribs['gradientUnits'], | ||
2284 | 'spread' => $attribs['spreadMethod'], | ||
2285 | 'color' => array() | ||
2286 | ); | ||
2287 | $last_gradid = $attribs['id']; | ||
2288 | $svg_class->svgAddGradient($attribs['id'],$tmp_gradient); | ||
2289 | return; | ||
2290 | } | ||
2291 | else if (strtolower($name) == 'radialgradient'){ | ||
2292 | $tmp_gradient = array( | ||
2293 | 'type' => 'radial', | ||
2294 | 'info' => array( | ||
2295 | 'x0' => $attribs['cx'], | ||
2296 | 'y0' => $attribs['cy'], | ||
2297 | 'x1' => $attribs['fx'], | ||
2298 | 'y1' => $attribs['fy'], | ||
2299 | 'r' => $attribs['r'] | ||
2300 | ), | ||
2301 | 'transform' => $attribs['gradientTransform'], | ||
2302 | 'units' => $attribs['gradientUnits'], | ||
2303 | 'spread' => $attribs['spreadMethod'], | ||
2304 | 'color' => array() | ||
2305 | ); | ||
2306 | $last_gradid = $attribs['id']; | ||
2307 | $svg_class->svgAddGradient($attribs['id'],$tmp_gradient); | ||
2308 | return; | ||
2309 | } | ||
2310 | else if (strtolower($name) == 'stop'){ | ||
2311 | if (!$last_gradid) break; | ||
2312 | if (isset($attribs['style']) AND preg_match('/stop-color:\s*([^;]*)/i',$attribs['style'],$m)) { | ||
2313 | $color = trim($m[1]); | ||
2314 | } else if (isset($attribs['stop-color'])) { | ||
2315 | $color = $attribs['stop-color']; | ||
2316 | } | ||
2317 | $col = $svg_class->mpdf_ref->ConvertColor($color); | ||
2318 | |||
2319 | if ($col{0}==3 || $col{0}==5) { // RGB | ||
2320 | $color_final = sprintf('%.3F %.3F %.3F',ord($col{1})/255,ord($col{2})/255,ord($col{3})/255); | ||
2321 | $svg_class->svg_gradient[$last_gradid]['colorspace']='RGB'; | ||
2322 | } | ||
2323 | else if ($col{0}==4 || $col{0}==6) { // CMYK | ||
2324 | $color_final = sprintf('%.3F %.3F %.3F %.3F',ord($col{1})/100,ord($col{2})/100,ord($col{3})/100,ord($col{4})/100); | ||
2325 | $svg_class->svg_gradient[$last_gradid]['colorspace']='CMYK'; | ||
2326 | } | ||
2327 | else if ($col{0}==1) { // Grayscale | ||
2328 | $color_final = sprintf('%.3F',ord($col{1})/255); | ||
2329 | $svg_class->svg_gradient[$last_gradid]['colorspace']='Gray'; | ||
2330 | } | ||
2331 | |||
2332 | $stop_opacity = 1; | ||
2333 | if (isset($attribs['style']) AND preg_match('/stop-opacity:\s*([0-9.]*)/i',$attribs['style'],$m)) { | ||
2334 | $stop_opacity = $m[1]; | ||
2335 | } else if (isset($attribs['stop-opacity'])) { | ||
2336 | $stop_opacity = $attribs['stop-opacity']; | ||
2337 | } | ||
2338 | else if ($col{0}==5) { // RGBa | ||
2339 | $stop_opacity = ord($col{4}/100); | ||
2340 | } | ||
2341 | else if ($col{0}==6) { // CMYKa | ||
2342 | $stop_opacity = ord($col{5}/100); | ||
2343 | } | ||
2344 | |||
2345 | $tmp_color = array( | ||
2346 | 'color' => $color_final, | ||
2347 | 'offset' => $attribs['offset'], | ||
2348 | 'opacity' => $stop_opacity | ||
2349 | ); | ||
2350 | array_push($svg_class->svg_gradient[$last_gradid]['color'],$tmp_color); | ||
2351 | return; | ||
2352 | } | ||
2353 | if ($svg_class->inDefs) { return; } | ||
2354 | |||
2355 | $svg_class->xbase = 0; | ||
2356 | $svg_class->ybase = 0; | ||
2357 | switch (strtolower($name)){ | ||
2358 | |||
2359 | // mPDF 5.0.039 - Don't output stuff inside <defs> | ||
2360 | case 'defs': | ||
2361 | $svg_class->inDefs = true; | ||
2362 | return; | ||
2363 | |||
2364 | case 'svg': | ||
2365 | $svg_class->svgOffset($attribs); | ||
2366 | break; | ||
2367 | |||
2368 | case 'path': | ||
2369 | $path = $attribs['d']; | ||
2370 | // mPDF 5.6.65 | ||
2371 | preg_match_all('/([MZLHVCSQTAmzlhvcsqta])([eE ,\-.\d]+)*/', $path, $commands, PREG_SET_ORDER); | ||
2372 | $path_cmd = ''; | ||
2373 | $svg_class->subPathInit = true; | ||
2374 | // mPDF 5.0.039 | ||
2375 | $svg_class->pathBBox = array(999999,999999,-999999,-999999); | ||
2376 | foreach($commands as $c){ | ||
2377 | if(count($c)==3 || $c[2]==''){ | ||
2378 | list($tmp, $command, $arguments) = $c; | ||
2379 | } | ||
2380 | else{ | ||
2381 | list($tmp, $command) = $c; | ||
2382 | $arguments = ''; | ||
2383 | } | ||
2384 | |||
2385 | $path_cmd .= $svg_class->svgPath($command, $arguments); | ||
2386 | } | ||
2387 | // mPDF 5.0.039 | ||
2388 | if ($svg_class->pathBBox[2]==-1999998) { $svg_class->pathBBox[2] = 100; } | ||
2389 | if ($svg_class->pathBBox[3]==-1999998) { $svg_class->pathBBox[3] = 100; } | ||
2390 | if ($svg_class->pathBBox[0]==999999) { $svg_class->pathBBox[0] = 0; } | ||
2391 | if ($svg_class->pathBBox[1]==999999) { $svg_class->pathBBox[1] = 0; } | ||
2392 | $critere_style = $attribs; | ||
2393 | unset($critere_style['d']); | ||
2394 | $path_style = $svg_class->svgDefineStyle($critere_style); | ||
2395 | break; | ||
2396 | |||
2397 | case 'rect': | ||
2398 | if (!isset($attribs['x'])) {$attribs['x'] = 0;} | ||
2399 | if (!isset($attribs['y'])) {$attribs['y'] = 0;} | ||
2400 | if (!isset($attribs['rx'])) {$attribs['rx'] = 0;} | ||
2401 | if (!isset($attribs['ry'])) {$attribs['ry'] = 0;} | ||
2402 | $arguments = array( | ||
2403 | 'x' => $attribs['x'], | ||
2404 | 'y' => $attribs['y'], | ||
2405 | 'w' => $attribs['width'], | ||
2406 | 'h' => $attribs['height'], | ||
2407 | 'rx' => $attribs['rx'], | ||
2408 | 'ry' => $attribs['ry'] | ||
2409 | ); | ||
2410 | $path_cmd = $svg_class->svgRect($arguments); | ||
2411 | $critere_style = $attribs; | ||
2412 | unset($critere_style['x'],$critere_style['y'],$critere_style['rx'],$critere_style['ry'],$critere_style['height'],$critere_style['width']); | ||
2413 | $path_style = $svg_class->svgDefineStyle($critere_style); | ||
2414 | break; | ||
2415 | |||
2416 | case 'circle': | ||
2417 | if (!isset($attribs['cx'])) {$attribs['cx'] = 0;} | ||
2418 | if (!isset($attribs['cy'])) {$attribs['cy'] = 0;} | ||
2419 | $arguments = array( | ||
2420 | 'cx' => $attribs['cx'], | ||
2421 | 'cy' => $attribs['cy'], | ||
2422 | 'rx' => $attribs['r'], | ||
2423 | 'ry' => $attribs['r'] | ||
2424 | ); | ||
2425 | $path_cmd = $svg_class->svgEllipse($arguments); | ||
2426 | $critere_style = $attribs; | ||
2427 | unset($critere_style['cx'],$critere_style['cy'],$critere_style['r']); | ||
2428 | $path_style = $svg_class->svgDefineStyle($critere_style); | ||
2429 | break; | ||
2430 | |||
2431 | case 'ellipse': | ||
2432 | if (!isset($attribs['cx'])) {$attribs['cx'] = 0;} | ||
2433 | if (!isset($attribs['cy'])) {$attribs['cy'] = 0;} | ||
2434 | $arguments = array( | ||
2435 | 'cx' => $attribs['cx'], | ||
2436 | 'cy' => $attribs['cy'], | ||
2437 | 'rx' => $attribs['rx'], | ||
2438 | 'ry' => $attribs['ry'] | ||
2439 | ); | ||
2440 | $path_cmd = $svg_class->svgEllipse($arguments); | ||
2441 | $critere_style = $attribs; | ||
2442 | unset($critere_style['cx'],$critere_style['cy'],$critere_style['rx'],$critere_style['ry']); | ||
2443 | $path_style = $svg_class->svgDefineStyle($critere_style); | ||
2444 | break; | ||
2445 | |||
2446 | case 'line': | ||
2447 | $arguments = array($attribs['x1'],$attribs['y1'],$attribs['x2'],$attribs['y2']); | ||
2448 | $path_cmd = $svg_class->svgPolyline($arguments,false); // mPDF 4.4.003 | ||
2449 | $critere_style = $attribs; | ||
2450 | unset($critere_style['x1'],$critere_style['y1'],$critere_style['x2'],$critere_style['y2']); | ||
2451 | $path_style = $svg_class->svgDefineStyle($critere_style); | ||
2452 | break; | ||
2453 | |||
2454 | case 'polyline': | ||
2455 | $path = $attribs['points']; | ||
2456 | preg_match_all('/[0-9\-\.]*/',$path, $tmp, PREG_SET_ORDER); | ||
2457 | $arguments = array(); | ||
2458 | for ($i=0;$i<count($tmp);$i++){ | ||
2459 | if ($tmp[$i][0] !=''){ | ||
2460 | array_push($arguments, $tmp[$i][0]); | ||
2461 | } | ||
2462 | } | ||
2463 | $path_cmd = $svg_class->svgPolyline($arguments); | ||
2464 | $critere_style = $attribs; | ||
2465 | unset($critere_style['points']); | ||
2466 | $path_style = $svg_class->svgDefineStyle($critere_style); | ||
2467 | break; | ||
2468 | |||
2469 | case 'polygon': | ||
2470 | $path = $attribs['points']; | ||
2471 | preg_match_all('/([\-]*[0-9\.]+)/',$path, $tmp); | ||
2472 | $arguments = array(); | ||
2473 | for ($i=0;$i<count($tmp[0]);$i++){ | ||
2474 | if ($tmp[0][$i] !=''){ | ||
2475 | array_push($arguments, $tmp[0][$i]); | ||
2476 | } | ||
2477 | } | ||
2478 | $path_cmd = $svg_class->svgPolygon($arguments); | ||
2479 | // definition du style de la forme: | ||
2480 | $critere_style = $attribs; | ||
2481 | unset($critere_style['points']); | ||
2482 | $path_style = $svg_class->svgDefineStyle($critere_style); | ||
2483 | break; | ||
2484 | |||
2485 | case 'a': | ||
2486 | if (isset($attribs['xlink:href'])) { | ||
2487 | unset($attribs['xlink:href']); // this should be a hyperlink | ||
2488 | // not handled like a xlink:href in other elements | ||
2489 | } // then continue like a <g> | ||
2490 | case 'g': | ||
2491 | $array_style = $svg_class->svgDefineStyle($attribs); | ||
2492 | if ($array_style['transformations']) { | ||
2493 | $svg_class->svgWriteString(' q '.$array_style['transformations']); | ||
2494 | } | ||
2495 | array_push($svg_class->svg_style,$array_style); | ||
2496 | |||
2497 | $svg_class->svgDefineTxtStyle($attribs); // mPDF 4.4.003 | ||
2498 | |||
2499 | break; | ||
2500 | |||
2501 | case 'text': | ||
2502 | $array_style = $svg_class->svgDefineStyle($attribs); | ||
2503 | if ($array_style['transformations']) { | ||
2504 | $svg_class->svgWriteString(' q '.$array_style['transformations']); | ||
2505 | } | ||
2506 | array_push($svg_class->svg_style,$array_style); | ||
2507 | |||
2508 | $svg_class->txt_data = array(); | ||
2509 | $svg_class->txt_data[0] = $attribs['x']; | ||
2510 | $svg_class->txt_data[1] = $attribs['y']; | ||
2511 | $critere_style = $attribs; | ||
2512 | unset($critere_style['x'], $critere_style['y']); | ||
2513 | $svg_class->svgDefineTxtStyle($critere_style); | ||
2514 | break; | ||
2515 | } | ||
2516 | |||
2517 | // | ||
2518 | //insertion des path et du style dans le flux de donné general. | ||
2519 | if (isset($path_cmd) && $path_cmd) { // mPDF 4.4.003 | ||
2520 | // mPDF 5.0 | ||
2521 | list($prestyle,$poststyle) = $svg_class->svgStyle($path_style, $attribs, strtolower($name)); | ||
2522 | if ($path_style['transformations']) { // transformation on an element | ||
2523 | $svg_class->svgWriteString(" q ".$path_style['transformations']. " $prestyle $path_cmd $poststyle" . " Q\n"); | ||
2524 | } | ||
2525 | else { | ||
2526 | $svg_class->svgWriteString("$prestyle $path_cmd $poststyle\n"); | ||
2527 | } | ||
2528 | } | ||
2529 | } | ||
2530 | |||
2531 | function characterData($parser, $data) | ||
2532 | { | ||
2533 | global $svg_class; | ||
2534 | if ($svg_class->inDefs) { return; } // mPDF 5.7.2 | ||
2535 | if(isset($svg_class->txt_data[2])) { | ||
2536 | $svg_class->txt_data[2] .= $data; | ||
2537 | } | ||
2538 | else { | ||
2539 | $svg_class->txt_data[2] = $data; | ||
2540 | } | ||
2541 | } | ||
2542 | |||
2543 | |||
2544 | function xml_svg2pdf_end($parser, $name){ | ||
2545 | global $svg_class; | ||
2546 | // Don't output stuff inside <defs> | ||
2547 | // mPDF 5.7.2 | ||
2548 | if ($name == 'defs') { | ||
2549 | $svg_class->inDefs = false; | ||
2550 | return; | ||
2551 | } | ||
2552 | if ($svg_class->inDefs) { return; } | ||
2553 | switch($name){ | ||
2554 | |||
2555 | case "g": | ||
2556 | case "a": | ||
2557 | $tmp = count($svg_class->svg_style)-1; | ||
2558 | $current_style = $svg_class->svg_style[$tmp]; | ||
2559 | if ($current_style['transformations']) { | ||
2560 | $svg_class->svgWriteString(" Q\n"); | ||
2561 | } | ||
2562 | array_pop($svg_class->svg_style); | ||
2563 | |||
2564 | array_pop($svg_class->txt_style); // mPDF 4.4.003 | ||
2565 | |||
2566 | break; | ||
2567 | case 'radialgradient': | ||
2568 | case 'lineargradient': | ||
2569 | $last_gradid = ''; | ||
2570 | break; | ||
2571 | case "text": | ||
2572 | $path_cmd = $svg_class->svgText(); | ||
2573 | // echo 'path >> '.$path_cmd."<br><br>"; | ||
2574 | // echo "style >> ".$get_style[1]."<br><br>"; | ||
2575 | $svg_class->svgWriteString($path_cmd); | ||
2576 | // mPDF 4.4.003 | ||
2577 | $tmp = count($svg_class->svg_style)-1; | ||
2578 | $current_style = $svg_class->svg_style[$tmp]; | ||
2579 | if ($current_style['transformations']) { | ||
2580 | $svg_class->svgWriteString(" Q\n"); | ||
2581 | } | ||
2582 | array_pop($svg_class->svg_style); | ||
2583 | |||
2584 | break; | ||
2585 | } | ||
2586 | // mPDF 5.0.039 - Don't output stuff inside <defs> | ||
2587 | if ($name == 'defs') { | ||
2588 | $svg_class->inDefs = false; | ||
2589 | } | ||
2590 | |||
2591 | } | ||
2592 | |||
2593 | } | ||
2594 | |||
2595 | $svg2pdf_xml=''; | ||
2596 | global $svg_class; | ||
2597 | $svg_class = $this; | ||
2598 | // mPDF 5.0.039 - Don't output stuff inside <defs> | ||
2599 | $svg_class->inDefs = false; | ||
2600 | $svg2pdf_xml_parser = xml_parser_create("utf-8"); | ||
2601 | xml_parser_set_option($svg2pdf_xml_parser, XML_OPTION_CASE_FOLDING, false); | ||
2602 | xml_set_element_handler($svg2pdf_xml_parser, "xml_svg2pdf_start", "xml_svg2pdf_end"); | ||
2603 | xml_set_character_data_handler($svg2pdf_xml_parser, "characterData"); | ||
2604 | xml_parse($svg2pdf_xml_parser, $data); | ||
2605 | // mPDF 4.4.003 | ||
2606 | if ($this->svg_error) { return false; } | ||
2607 | else { | ||
2608 | return array('x'=>$this->svg_info['x']*$this->kp,'y'=>-$this->svg_info['y']*$this->kp,'w'=>$this->svg_info['w']*$this->kp,'h'=>-$this->svg_info['h']*$this->kp,'data'=>$svg_class->svg_string); | ||
2609 | } | ||
2610 | |||
2611 | } | ||
2612 | |||
2613 | } | ||
2614 | |||
2615 | // END OF CLASS | ||
2616 | |||
2617 | |||
2618 | // mPDF 5.0.040 | ||
2619 | function calc_bezier_bbox($start, $c) { | ||
2620 | $P0 = array($start[0],$start[1]); | ||
2621 | $P1 = array($c[0],$c[1]); | ||
2622 | $P2 = array($c[2],$c[3]); | ||
2623 | $P3 = array($c[4],$c[5]); | ||
2624 | $bounds = array(); | ||
2625 | $bounds[0][] = $P0[0]; | ||
2626 | $bounds[1][] = $P0[1]; | ||
2627 | $bounds[0][] = $P3[0]; | ||
2628 | $bounds[1][] = $P3[1]; | ||
2629 | for ($i=0;$i<=1;$i++) { | ||
2630 | $b = 6 * $P0[$i] - 12 * $P1[$i] + 6 * $P2[$i]; | ||
2631 | $a = -3 * $P0[$i] + 9 * $P1[$i] - 9 * $P2[$i] + 3 * $P3[$i]; | ||
2632 | $c = 3 * $P1[$i] - 3 * $P0[$i]; | ||
2633 | if ($a == 0) { | ||
2634 | if ($b == 0) { continue; } | ||
2635 | $t = -$c / $b; | ||
2636 | if ($t>0 && $t<1) { | ||
2637 | $bounds[$i][] = (pow((1-$t),3) * $P0[$i] + 3 * pow((1-$t),2) * $t * $P1[$i] + 3 * (1-$t) * pow($t,2) * $P2[$i] + pow($t,3) * $P3[$i]); | ||
2638 | } | ||
2639 | continue; | ||
2640 | } | ||
2641 | $b2ac = pow($b, 2) - 4 * $c * $a; | ||
2642 | if ($b2ac < 0) { continue; } | ||
2643 | $t1 = (-$b + sqrt($b2ac))/(2 * $a); | ||
2644 | if ($t1>0 && $t1<1) { | ||
2645 | $bounds[$i][] = (pow((1-$t1),3) * $P0[$i] + 3 * pow((1-$t1),2) * $t1 * $P1[$i] + 3 * (1-$t1) * pow($t1,2) * $P2[$i] + pow($t1,3) * $P3[$i]); | ||
2646 | } | ||
2647 | $t2 = (-$b - sqrt($b2ac))/(2 * $a); | ||
2648 | if ($t2>0 && $t2<1) { | ||
2649 | $bounds[$i][] = (pow((1-$t2),3) * $P0[$i] + 3 * pow((1-$t2),2) * $t2 * $P1[$i] + 3 * (1-$t2) * pow($t2,2) * $P2[$i] + pow($t2,3) * $P3[$i]); | ||
2650 | } | ||
2651 | } | ||
2652 | $x = min($bounds[0]); | ||
2653 | $x2 = max($bounds[0]); | ||
2654 | $y = min($bounds[1]); | ||
2655 | $y2 = max($bounds[1]); | ||
2656 | return array($x, $y, $x2, $y2); | ||
2657 | } | ||
2658 | |||
2659 | // mPDF 5.0.040 | ||
2660 | function _testIntersectCircle($cx, $cy, $cr) { | ||
2661 | // Tests whether a circle fully encloses a rectangle 0,0,1,1 | ||
2662 | // to see if any further radial gradients need adding (SVG) | ||
2663 | // If centre of circle is inside 0,0,1,1 square | ||
2664 | if ($cx >= 0 && $cx <= 1 && $cy >= 0 && $cy <= 1) { | ||
2665 | $maxd = 1.5; | ||
2666 | } | ||
2667 | // distance to four corners | ||
2668 | else { | ||
2669 | $d1 = sqrt(pow(($cy-0),2) + pow(($cx-0),2)); | ||
2670 | $d2 = sqrt(pow(($cy-1),2) + pow(($cx-0),2)); | ||
2671 | $d3 = sqrt(pow(($cy-0),2) + pow(($cx-1),2)); | ||
2672 | $d4 = sqrt(pow(($cy-1),2) + pow(($cx-1),2)); | ||
2673 | $maxd = max($d1,$d2,$d3,$d4); | ||
2674 | } | ||
2675 | if ($cr < $maxd) { return true; } | ||
2676 | else { return false; } | ||
2677 | } | ||
2678 | |||
2679 | // mPDF 5.0.040 | ||
2680 | function _testIntersect($x1, $y1, $x2, $y2, $x3, $y3, $x4, $y4) { | ||
2681 | // Tests whether line (x1, y1) and (x2, y2) [a gradient axis (perpendicular)] | ||
2682 | // intersects with a specific line segment (x3, y3) and (x4, y4) | ||
2683 | $a1 = $y2-$y1; | ||
2684 | $b1 = $x1-$x2; | ||
2685 | $c1 = $a1*$x1+$b1*$y1; | ||
2686 | $a2 = $y4-$y3; | ||
2687 | $b2 = $x3-$x4; | ||
2688 | $c2 = $a2*$x3+$b2*$y3; | ||
2689 | $det = $a1*$b2 - $a2*$b1; | ||
2690 | if($det == 0){ //Lines are parallel | ||
2691 | return false; | ||
2692 | } | ||
2693 | else{ | ||
2694 | $x = ($b2*$c1 - $b1*$c2)/$det; | ||
2695 | $y = ($a1*$c2 - $a2*$c1)/$det; | ||
2696 | if ($x >= $x3 && $x <= $x4 && $y >= $y3 && $y <= $y4) { return true; } | ||
2697 | } | ||
2698 | return false; | ||
2699 | } | ||
2700 | |||
2701 | |||
2702 | |||
2703 | ?> \ No newline at end of file | ||