PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.3
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.3
2.4.3 2.4.4 2.4.2 2.4.0 2.4.1 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.2.0 2.1.21 2.1.20 2.1.19 2.1.18 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 All 60 releases
easy-invoice / vendor / dompdf / php-svg-lib / src / Svg / Surface / SurfaceCpdf.php

SurfaceCpdf.php in Easy Invoice – Invoice Generator, PDF Quotes & Payments 2.4.3, at vendor/dompdf/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php

495 lines 13.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package php-svg-lib
4 * @link http://github.com/dompdf/php-svg-lib
5 * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html
6 */
7
8 namespace Svg\Surface;
9
10 use Svg\Document;
11 use Svg\Style;
12
13 class SurfaceCpdf implements SurfaceInterface
14 {
15 const DEBUG = false;
16
17 /** @var \Svg\Surface\CPdf */
18 private $canvas;
19
20 private $width;
21 private $height;
22
23 /** @var Style */
24 private $style;
25
26 public function __construct(Document $doc, $canvas = null)
27 {
28 if (self::DEBUG) echo __FUNCTION__ . "\n";
29
30 $dimensions = $doc->getDimensions();
31 $w = $dimensions["width"];
32 $h = $dimensions["height"];
33
34 if (!$canvas) {
35 $canvas = new \Svg\Surface\CPdf(array(0, 0, $w, $h));
36 $refl = new \ReflectionClass($canvas);
37 $canvas->fontcache = realpath(dirname($refl->getFileName()) . "/../../fonts/")."/";
38 }
39
40 // Flip PDF coordinate system so that the origin is in
41 // the top left rather than the bottom left
42 $canvas->transform(array(
43 1, 0,
44 0, -1,
45 0, $h
46 ));
47
48 $this->width = $w;
49 $this->height = $h;
50
51 $this->canvas = $canvas;
52 }
53
54 function out()
55 {
56 if (self::DEBUG) echo __FUNCTION__ . "\n";
57 return $this->canvas->output();
58 }
59
60 public function save()
61 {
62 if (self::DEBUG) echo __FUNCTION__ . "\n";
63 $this->canvas->save();
64 }
65
66 public function restore()
67 {
68 if (self::DEBUG) echo __FUNCTION__ . "\n";
69 $this->canvas->restore();
70 }
71
72 public function scale($x, $y)
73 {
74 if (self::DEBUG) echo __FUNCTION__ . "\n";
75
76 $this->transform($x, 0, 0, $y, 0, 0);
77 }
78
79 public function rotate($angle)
80 {
81 if (self::DEBUG) echo __FUNCTION__ . "\n";
82
83 $a = deg2rad($angle);
84 $cos_a = cos($a);
85 $sin_a = sin($a);
86
87 $this->transform(
88 $cos_a, $sin_a,
89 -$sin_a, $cos_a,
90 0, 0
91 );
92 }
93
94 public function translate($x, $y)
95 {
96 if (self::DEBUG) echo __FUNCTION__ . "\n";
97
98 $this->transform(
99 1, 0,
100 0, 1,
101 $x, $y
102 );
103 }
104
105 public function transform($a, $b, $c, $d, $e, $f)
106 {
107 if (self::DEBUG) echo __FUNCTION__ . "\n";
108
109 $this->canvas->transform(array($a, $b, $c, $d, $e, $f));
110 }
111
112 public function beginPath()
113 {
114 if (self::DEBUG) echo __FUNCTION__ . "\n";
115 // TODO: Implement beginPath() method.
116 }
117
118 public function closePath()
119 {
120 if (self::DEBUG) echo __FUNCTION__ . "\n";
121 $this->canvas->closePath();
122 }
123
124 public function fillStroke(bool $close = false)
125 {
126 if (self::DEBUG) echo __FUNCTION__ . "\n";
127 $this->canvas->fillStroke($close);
128 }
129
130 public function clip()
131 {
132 if (self::DEBUG) echo __FUNCTION__ . "\n";
133 $this->canvas->clip();
134 }
135
136 public function fillText($text, $x, $y, $maxWidth = null)
137 {
138 if (self::DEBUG) echo __FUNCTION__ . "\n";
139 $this->canvas->addText($x, $y, $this->style->fontSize, $text);
140 }
141
142 public function strokeText($text, $x, $y, $maxWidth = null)
143 {
144 if (self::DEBUG) echo __FUNCTION__ . "\n";
145 $this->canvas->addText($x, $y, $this->style->fontSize, $text);
146 }
147
148 public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null)
149 {
150 if (self::DEBUG) echo __FUNCTION__ . "\n";
151
152 if (strpos($image, "data:") === 0) {
153 $parts = explode(',', $image, 2);
154
155 $data = $parts[1];
156 $base64 = false;
157
158 $token = strtok($parts[0], ';');
159 while ($token !== false) {
160 if ($token == 'base64') {
161 $base64 = true;
162 }
163
164 $token = strtok(';');
165 }
166
167 if ($base64) {
168 $data = base64_decode($data);
169 }
170 }
171 else {
172 $data = file_get_contents($image);
173 }
174
175 $image = tempnam(sys_get_temp_dir(), "svg");
176 file_put_contents($image, $data);
177
178 $img = $this->image($image, $sx, $sy, $sw, $sh, "normal");
179
180
181 unlink($image);
182 }
183
184 public static function getimagesize($filename)
185 {
186 static $cache = array();
187
188 if (isset($cache[$filename])) {
189 return $cache[$filename];
190 }
191
192 list($width, $height, $type) = getimagesize($filename);
193
194 if ($width == null || $height == null) {
195 $data = file_get_contents($filename, null, null, 0, 26);
196
197 if (substr($data, 0, 2) === "BM") {
198 $meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data);
199 $width = (int)$meta['width'];
200 $height = (int)$meta['height'];
201 $type = IMAGETYPE_BMP;
202 }
203 }
204
205 return $cache[$filename] = array($width, $height, $type);
206 }
207
208 function image($img, $x, $y, $w, $h, $resolution = "normal")
209 {
210 list($width, $height, $type) = $this->getimagesize($img);
211
212 switch ($type) {
213 case IMAGETYPE_JPEG:
214 $this->canvas->addJpegFromFile($img, $x, $y - $h, $w, $h);
215 break;
216
217 case IMAGETYPE_GIF:
218 case IMAGETYPE_BMP:
219 // @todo use cache for BMP and GIF
220 $img = $this->_convert_gif_bmp_to_png($img, $type);
221
222 case IMAGETYPE_PNG:
223 $this->canvas->addPngFromFile($img, $x, $y - $h, $w, $h);
224 break;
225
226 default:
227 }
228 }
229
230 public function lineTo($x, $y)
231 {
232 if (self::DEBUG) echo __FUNCTION__ . "\n";
233 $this->canvas->lineTo($x, $y);
234 }
235
236 public function moveTo($x, $y)
237 {
238 if (self::DEBUG) echo __FUNCTION__ . "\n";
239 $this->canvas->moveTo($x, $y);
240 }
241
242 public function quadraticCurveTo($cpx, $cpy, $x, $y)
243 {
244 if (self::DEBUG) echo __FUNCTION__ . "\n";
245
246 // FIXME not accurate
247 $this->canvas->quadTo($cpx, $cpy, $x, $y);
248 }
249
250 public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y)
251 {
252 if (self::DEBUG) echo __FUNCTION__ . "\n";
253 $this->canvas->curveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y);
254 }
255
256 public function arcTo($x1, $y1, $x2, $y2, $radius)
257 {
258 if (self::DEBUG) echo __FUNCTION__ . "\n";
259 }
260
261 public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false)
262 {
263 if (self::DEBUG) echo __FUNCTION__ . "\n";
264 $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, $startAngle, $endAngle, false, false, false, true);
265 }
266
267 public function circle($x, $y, $radius)
268 {
269 if (self::DEBUG) echo __FUNCTION__ . "\n";
270 $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, 0, 360, true, false, false, false);
271 }
272
273 public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise)
274 {
275 if (self::DEBUG) echo __FUNCTION__ . "\n";
276 $this->canvas->ellipse($x, $y, $radiusX, $radiusY, 0, 8, 0, 360, false, false, false, false);
277 }
278
279 public function fillRect($x, $y, $w, $h)
280 {
281 if (self::DEBUG) echo __FUNCTION__ . "\n";
282 $this->rect($x, $y, $w, $h);
283 $this->fill();
284 }
285
286 public function rect($x, $y, $w, $h, $rx = 0, $ry = 0)
287 {
288 if (self::DEBUG) echo __FUNCTION__ . "\n";
289
290 $canvas = $this->canvas;
291
292 if ($rx <= 0.000001/* && $ry <= 0.000001*/) {
293 $canvas->rect($x, $y, $w, $h);
294
295 return;
296 }
297
298 $rx = min($rx, $w / 2);
299 $rx = min($rx, $h / 2);
300
301 /* Define a path for a rectangle with corners rounded by a given radius.
302 * Start from the lower left corner and proceed counterclockwise.
303 */
304 $this->moveTo($x + $rx, $y);
305
306 /* Start of the arc segment in the lower right corner */
307 $this->lineTo($x + $w - $rx, $y);
308
309 /* Arc segment in the lower right corner */
310 $this->arc($x + $w - $rx, $y + $rx, $rx, 270, 360);
311
312 /* Start of the arc segment in the upper right corner */
313 $this->lineTo($x + $w, $y + $h - $rx );
314
315 /* Arc segment in the upper right corner */
316 $this->arc($x + $w - $rx, $y + $h - $rx, $rx, 0, 90);
317
318 /* Start of the arc segment in the upper left corner */
319 $this->lineTo($x + $rx, $y + $h);
320
321 /* Arc segment in the upper left corner */
322 $this->arc($x + $rx, $y + $h - $rx, $rx, 90, 180);
323
324 /* Start of the arc segment in the lower left corner */
325 $this->lineTo($x , $y + $rx);
326
327 /* Arc segment in the lower left corner */
328 $this->arc($x + $rx, $y + $rx, $rx, 180, 270);
329 }
330
331 public function fill()
332 {
333 if (self::DEBUG) echo __FUNCTION__ . "\n";
334 $this->canvas->fill();
335 }
336
337 public function strokeRect($x, $y, $w, $h)
338 {
339 if (self::DEBUG) echo __FUNCTION__ . "\n";
340 $this->rect($x, $y, $w, $h);
341 $this->stroke();
342 }
343
344 public function stroke(bool $close = false)
345 {
346 if (self::DEBUG) echo __FUNCTION__ . "\n";
347 $this->canvas->stroke($close);
348 }
349
350 public function endPath()
351 {
352 if (self::DEBUG) echo __FUNCTION__ . "\n";
353 $this->canvas->endPath();
354 }
355
356 public function measureText($text)
357 {
358 if (self::DEBUG) echo __FUNCTION__ . "\n";
359 $style = $this->getStyle();
360 $this->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight);
361
362 return $this->canvas->getTextWidth($this->getStyle()->fontSize, $text);
363 }
364
365 public function getStyle()
366 {
367 if (self::DEBUG) echo __FUNCTION__ . "\n";
368 return $this->style;
369 }
370
371 public function setStyle(Style $style)
372 {
373 if (self::DEBUG) echo __FUNCTION__ . "\n";
374
375 $this->style = $style;
376 $canvas = $this->canvas;
377
378 if (is_array($style->stroke) && $stroke = $style->stroke) {
379 $canvas->setStrokeColor(array((float)$stroke[0]/255, (float)$stroke[1]/255, (float)$stroke[2]/255), true);
380 }
381
382 if (is_array($style->fill) && $fill = $style->fill) {
383 $canvas->setColor(array((float)$fill[0]/255, (float)$fill[1]/255, (float)$fill[2]/255), true);
384 }
385
386 if ($fillRule = strtolower($style->fillRule)) {
387 $canvas->setFillRule($fillRule);
388 }
389
390 $opacity = $style->opacity;
391 if ($opacity !== null && $opacity < 1.0) {
392 $canvas->setLineTransparency("Normal", $opacity);
393 $canvas->currentLineTransparency = null;
394
395 $canvas->setFillTransparency("Normal", $opacity);
396 $canvas->currentFillTransparency = null;
397 }
398 else {
399 $fillOpacity = $style->fillOpacity;
400 if ($fillOpacity !== null && $fillOpacity < 1.0) {
401 $canvas->setFillTransparency("Normal", $fillOpacity);
402 $canvas->currentFillTransparency = null;
403 }
404
405 $strokeOpacity = $style->strokeOpacity;
406 if ($strokeOpacity !== null && $strokeOpacity < 1.0) {
407 $canvas->setLineTransparency("Normal", $strokeOpacity);
408 $canvas->currentLineTransparency = null;
409 }
410 }
411
412 $dashArray = null;
413 if ($style->strokeDasharray) {
414 $dashArray = preg_split('/\s*,\s*/', $style->strokeDasharray);
415 }
416
417
418 $phase=0;
419 if ($style->strokeDashoffset) {
420 $phase = $style->strokeDashoffset;
421 }
422
423
424 $canvas->setLineStyle(
425 $style->strokeWidth,
426 $style->strokeLinecap,
427 $style->strokeLinejoin,
428 $dashArray,
429 $phase
430 );
431
432 $this->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight);
433 }
434
435 public function setFont($family, $style, $weight)
436 {
437 $map = [
438 "serif" => "times",
439 "sans-serif" => "helvetica",
440 "fantasy" => "symbol",
441 "cursive" => "times",
442 "monospace" => "courier"
443 ];
444
445 $styleMap = [
446 "courier" => [
447 "" => "Courier",
448 "b" => "Courier-Bold",
449 "i" => "Courier-Oblique",
450 "bi" => "Courier-BoldOblique",
451 ],
452 "helvetica" => [
453 "" => "Helvetica",
454 "b" => "Helvetica-Bold",
455 "i" => "Helvetica-Oblique",
456 "bi" => "Helvetica-BoldOblique",
457 ],
458 "symbol" => [
459 "" => "Symbol"
460 ],
461 "times" => [
462 "" => "Times-Roman",
463 "b" => "Times-Bold",
464 "i" => "Times-Italic",
465 "bi" => "Times-BoldItalic",
466 ],
467 ];
468
469 $family_lc = strtolower($family);
470 if (isset($map[$family_lc])) {
471 $family = $map[$family_lc];
472 }
473
474 if (isset($styleMap[$family])) {
475 $key = "";
476
477 $weight = strtolower($weight);
478 if ($weight === "bold" || $weight === "bolder" || (is_numeric($weight) && $weight >= 600)) {
479 $key .= "b";
480 }
481
482 $style = strtolower($style);
483 if ($style === "italic" || $style === "oblique") {
484 $key .= "i";
485 }
486
487 if (isset($styleMap[$family][$key])) {
488 $family = $styleMap[$family][$key];
489 }
490 }
491
492 $this->canvas->selectFont("$family.afm");
493 }
494 }
495