PluginProbe
Easy Invoice – Invoice Generator, PDF Quotes & Payments / 2.4.2
Easy Invoice – Invoice Generator, PDF Quotes & Payments v2.4.2
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 / SurfacePDFLib.php

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

430 lines 11.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\Style;
11 use Svg\Document;
12
13 class SurfacePDFLib implements SurfaceInterface
14 {
15 const DEBUG = false;
16
17 private $canvas;
18
19 private $width;
20 private $height;
21
22 /** @var Style */
23 private $style;
24
25 public function __construct(Document $doc, $canvas = null)
26 {
27 if (self::DEBUG) echo __FUNCTION__ . "\n";
28
29 $dimensions = $doc->getDimensions();
30 $w = $dimensions["width"];
31 $h = $dimensions["height"];
32
33 if (!$canvas) {
34 $canvas = new \PDFlib();
35
36 /* all strings are expected as utf8 */
37 $canvas->set_option("stringformat=utf8");
38 $canvas->set_option("errorpolicy=return");
39
40 /* open new PDF file; insert a file name to create the PDF on disk */
41 if ($canvas->begin_document("", "") == 0) {
42 die("Error: " . $canvas->get_errmsg());
43 }
44 $canvas->set_info("Creator", "PDFlib starter sample");
45 $canvas->set_info("Title", "starter_graphics");
46
47 $canvas->begin_page_ext($w, $h, "");
48 }
49
50 // Flip PDF coordinate system so that the origin is in
51 // the top left rather than the bottom left
52 $canvas->setmatrix(
53 1, 0,
54 0, -1,
55 0, $h
56 );
57
58 $this->width = $w;
59 $this->height = $h;
60
61 $this->canvas = $canvas;
62 }
63
64 function out()
65 {
66 if (self::DEBUG) echo __FUNCTION__ . "\n";
67
68 $this->canvas->end_page_ext("");
69 $this->canvas->end_document("");
70
71 return $this->canvas->get_buffer();
72 }
73
74 public function save()
75 {
76 if (self::DEBUG) echo __FUNCTION__ . "\n";
77 $this->canvas->save();
78 }
79
80 public function restore()
81 {
82 if (self::DEBUG) echo __FUNCTION__ . "\n";
83 $this->canvas->restore();
84 }
85
86 public function scale($x, $y)
87 {
88 if (self::DEBUG) echo __FUNCTION__ . "\n";
89 $this->canvas->scale($x, $y);
90 }
91
92 public function rotate($angle)
93 {
94 if (self::DEBUG) echo __FUNCTION__ . "\n";
95 $this->canvas->rotate($angle);
96 }
97
98 public function translate($x, $y)
99 {
100 if (self::DEBUG) echo __FUNCTION__ . "\n";
101 $this->canvas->translate($x, $y);
102 }
103
104 public function transform($a, $b, $c, $d, $e, $f)
105 {
106 if (self::DEBUG) echo __FUNCTION__ . "\n";
107 $this->canvas->concat($a, $b, $c, $d, $e, $f);
108 }
109
110 public function beginPath()
111 {
112 if (self::DEBUG) echo __FUNCTION__ . "\n";
113 // TODO: Implement beginPath() method.
114 }
115
116 public function closePath()
117 {
118 if (self::DEBUG) echo __FUNCTION__ . "\n";
119 $this->canvas->closepath();
120 }
121
122 public function fillStroke(bool $close = false)
123 {
124 if (self::DEBUG) echo __FUNCTION__ . "\n";
125 if ($close) {
126 $this->canvas->closepath_fill_stroke();
127 } else {
128 $this->canvas->fill_stroke();
129 }
130 }
131
132 public function clip()
133 {
134 if (self::DEBUG) echo __FUNCTION__ . "\n";
135 $this->canvas->clip();
136 }
137
138 public function fillText($text, $x, $y, $maxWidth = null)
139 {
140 if (self::DEBUG) echo __FUNCTION__ . "\n";
141 $this->canvas->set_text_pos($x, $y);
142 $this->canvas->show($text);
143 }
144
145 public function strokeText($text, $x, $y, $maxWidth = null)
146 {
147 if (self::DEBUG) echo __FUNCTION__ . "\n";
148 // TODO: Implement drawImage() method.
149 }
150
151 public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null)
152 {
153 if (self::DEBUG) echo __FUNCTION__ . "\n";
154
155 if (strpos($image, "data:") === 0) {
156 $data = substr($image, strpos($image, ";") + 1);
157 if (strpos($data, "base64") === 0) {
158 $data = base64_decode(substr($data, 7));
159 }
160 }
161 else {
162 $data = file_get_contents($image);
163 }
164
165 $image = tempnam(sys_get_temp_dir(), "svg");
166 file_put_contents($image, $data);
167
168 $img = $this->canvas->load_image("auto", $image, "");
169
170 $sy = $sy - $sh;
171 $this->canvas->fit_image($img, $sx, $sy, 'boxsize={' . "$sw $sh" . '} fitmethod=entire');
172
173 unlink($image);
174 }
175
176 public function lineTo($x, $y)
177 {
178 if (self::DEBUG) echo __FUNCTION__ . "\n";
179 $this->canvas->lineto($x, $y);
180 }
181
182 public function moveTo($x, $y)
183 {
184 if (self::DEBUG) echo __FUNCTION__ . "\n";
185 $this->canvas->moveto($x, $y);
186 }
187
188 public function quadraticCurveTo($cpx, $cpy, $x, $y)
189 {
190 if (self::DEBUG) echo __FUNCTION__ . "\n";
191
192 // FIXME not accurate
193 $this->canvas->curveTo($cpx, $cpy, $cpx, $cpy, $x, $y);
194 }
195
196 public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y)
197 {
198 if (self::DEBUG) echo __FUNCTION__ . "\n";
199 $this->canvas->curveto($cp1x, $cp1y, $cp2x, $cp2y, $x, $y);
200 }
201
202 public function arcTo($x1, $y1, $x2, $y2, $radius)
203 {
204 if (self::DEBUG) echo __FUNCTION__ . "\n";
205 }
206
207 public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false)
208 {
209 if (self::DEBUG) echo __FUNCTION__ . "\n";
210 $this->canvas->arc($x, $y, $radius, $startAngle, $endAngle);
211 }
212
213 public function circle($x, $y, $radius)
214 {
215 if (self::DEBUG) echo __FUNCTION__ . "\n";
216 $this->canvas->circle($x, $y, $radius);
217 }
218
219 public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise)
220 {
221 if (self::DEBUG) echo __FUNCTION__ . "\n";
222 $this->canvas->ellipse($x, $y, $radiusX, $radiusY);
223 }
224
225 public function fillRect($x, $y, $w, $h)
226 {
227 if (self::DEBUG) echo __FUNCTION__ . "\n";
228 $this->rect($x, $y, $w, $h);
229 $this->fill();
230 }
231
232 public function rect($x, $y, $w, $h, $rx = 0, $ry = 0)
233 {
234 if (self::DEBUG) echo __FUNCTION__ . "\n";
235
236 $canvas = $this->canvas;
237
238 if ($rx <= 0.000001/* && $ry <= 0.000001*/) {
239 $canvas->rect($x, $y, $w, $h);
240
241 return;
242 }
243
244 /* Define a path for a rectangle with corners rounded by a given radius.
245 * Start from the lower left corner and proceed counterclockwise.
246 */
247 $canvas->moveto($x + $rx, $y);
248
249 /* Start of the arc segment in the lower right corner */
250 $canvas->lineto($x + $w - $rx, $y);
251
252 /* Arc segment in the lower right corner */
253 $canvas->arc($x + $w - $rx, $y + $rx, $rx, 270, 360);
254
255 /* Start of the arc segment in the upper right corner */
256 $canvas->lineto($x + $w, $y + $h - $rx );
257
258 /* Arc segment in the upper right corner */
259 $canvas->arc($x + $w - $rx, $y + $h - $rx, $rx, 0, 90);
260
261 /* Start of the arc segment in the upper left corner */
262 $canvas->lineto($x + $rx, $y + $h);
263
264 /* Arc segment in the upper left corner */
265 $canvas->arc($x + $rx, $y + $h - $rx, $rx, 90, 180);
266
267 /* Start of the arc segment in the lower left corner */
268 $canvas->lineto($x , $y + $rx);
269
270 /* Arc segment in the lower left corner */
271 $canvas->arc($x + $rx, $y + $rx, $rx, 180, 270);
272 }
273
274 public function fill()
275 {
276 if (self::DEBUG) echo __FUNCTION__ . "\n";
277 $this->canvas->fill();
278 }
279
280 public function strokeRect($x, $y, $w, $h)
281 {
282 if (self::DEBUG) echo __FUNCTION__ . "\n";
283 $this->rect($x, $y, $w, $h);
284 $this->stroke();
285 }
286
287 public function stroke(bool $close = false)
288 {
289 if (self::DEBUG) echo __FUNCTION__ . "\n";
290 if ($close) {
291 $this->canvas->closepath_stroke();
292 } else {
293 $this->canvas->stroke();
294 }
295 }
296
297 public function endPath()
298 {
299 if (self::DEBUG) echo __FUNCTION__ . "\n";
300 $this->canvas->endPath();
301 }
302
303 public function measureText($text)
304 {
305 if (self::DEBUG) echo __FUNCTION__ . "\n";
306 $style = $this->getStyle();
307 $font = $this->getFont($style->fontFamily, $style->fontStyle);
308
309 return $this->canvas->stringwidth($text, $font, $this->getStyle()->fontSize);
310 }
311
312 public function getStyle()
313 {
314 if (self::DEBUG) echo __FUNCTION__ . "\n";
315 return $this->style;
316 }
317
318 public function setStyle(Style $style)
319 {
320 if (self::DEBUG) echo __FUNCTION__ . "\n";
321
322 $this->style = $style;
323 $canvas = $this->canvas;
324
325 if (is_array($style->stroke) && $stroke = $style->stroke) {
326 $canvas->setcolor(
327 "stroke",
328 "rgb",
329 $stroke[0] / 255,
330 $stroke[1] / 255,
331 $stroke[2] / 255,
332 null
333 );
334 }
335
336 if (is_array($style->fill) && $fill = $style->fill) {
337 $canvas->setcolor(
338 "fill",
339 "rgb",
340 $fill[0] / 255,
341 $fill[1] / 255,
342 $fill[2] / 255,
343 null
344 );
345 }
346
347 if ($fillRule = strtolower($style->fillRule)) {
348 $map = array(
349 "nonzero" => "winding",
350 "evenodd" => "evenodd",
351 );
352
353 if (isset($map[$fillRule])) {
354 $fillRule = $map[$fillRule];
355
356 $canvas->set_parameter("fillrule", $fillRule);
357 }
358 }
359
360 $opts = array();
361 if ($style->strokeWidth > 0.000001) {
362 $opts[] = "linewidth=$style->strokeWidth";
363 }
364
365 if (in_array($style->strokeLinecap, array("butt", "round", "projecting"))) {
366 $opts[] = "linecap=$style->strokeLinecap";
367 }
368
369 if (in_array($style->strokeLinejoin, array("miter", "round", "bevel"))) {
370 $opts[] = "linejoin=$style->strokeLinejoin";
371 }
372
373 $canvas->set_graphics_option(implode(" ", $opts));
374
375 $opts = array();
376 $opacity = $style->opacity;
377 if ($opacity !== null && $opacity < 1.0) {
378 $opts[] = "opacityfill=$opacity";
379 $opts[] = "opacitystroke=$opacity";
380 }
381 else {
382 $fillOpacity = $style->fillOpacity;
383 if ($fillOpacity !== null && $fillOpacity < 1.0) {
384 $opts[] = "opacityfill=$fillOpacity";
385 }
386
387 $strokeOpacity = $style->strokeOpacity;
388 if ($strokeOpacity !== null && $strokeOpacity < 1.0) {
389 $opts[] = "opacitystroke=$strokeOpacity";
390 }
391 }
392
393 if (count($opts)) {
394 $gs = $canvas->create_gstate(implode(" ", $opts));
395 $canvas->set_gstate($gs);
396 }
397
398 $font = $this->getFont($style->fontFamily, $style->fontStyle);
399 if ($font) {
400 $canvas->setfont($font, $style->fontSize);
401 }
402 }
403
404 private function getFont($family, $style)
405 {
406 $map = array(
407 "serif" => "Times",
408 "sans-serif" => "Helvetica",
409 "fantasy" => "Symbol",
410 "cursive" => "Times",
411 "monospace" => "Courier",
412
413 "arial" => "Helvetica",
414 "verdana" => "Helvetica",
415 );
416
417 $family = strtolower($family);
418 if (isset($map[$family])) {
419 $family = $map[$family];
420 }
421
422 return $this->canvas->load_font($family, "unicode", "fontstyle=$style");
423 }
424
425 public function setFont($family, $style, $weight)
426 {
427 // TODO: Implement setFont() method.
428 }
429 }
430