commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-new / civicrm / vendor / phenx / php-svg-lib / src / Svg / Surface / SurfaceCpdf.php
1 <?php
2 /**
3 * @package php-svg-lib
4 * @link http://github.com/PhenX/php-svg-lib
5 * @author Fabien Ménager <fabien.menager@gmail.com>
6 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7 */
8
9 namespace Svg\Surface;
10
11 use Svg\Document;
12 use Svg\Style;
13
14 class SurfaceCpdf implements SurfaceInterface
15 {
16 const DEBUG = false;
17
18 /** @var Cpdf */
19 private $canvas;
20
21 private $width;
22 private $height;
23
24 /** @var Style */
25 private $style;
26
27 public function __construct(Document $doc, $canvas = null)
28 {
29 if (self::DEBUG) echo __FUNCTION__ . "\n";
30
31 $dimensions = $doc->getDimensions();
32 $w = $dimensions["width"];
33 $h = $dimensions["height"];
34
35 if (!$canvas) {
36 $canvas = new CPdf(array(0, 0, $w, $h));
37 }
38
39 // Flip PDF coordinate system so that the origin is in
40 // the top left rather than the bottom left
41 $canvas->transform(array(
42 1, 0,
43 0, -1,
44 0, $h
45 ));
46
47 $this->width = $w;
48 $this->height = $h;
49
50 $this->canvas = $canvas;
51 }
52
53 function out()
54 {
55 if (self::DEBUG) echo __FUNCTION__ . "\n";
56 return $this->canvas->output();
57 }
58
59 public function save()
60 {
61 if (self::DEBUG) echo __FUNCTION__ . "\n";
62 $this->canvas->save();
63 }
64
65 public function restore()
66 {
67 if (self::DEBUG) echo __FUNCTION__ . "\n";
68 $this->canvas->restore();
69 }
70
71 public function scale($x, $y)
72 {
73 if (self::DEBUG) echo __FUNCTION__ . "\n";
74
75 $this->transform($x, 0, 0, $y, 0, 0);
76 }
77
78 public function rotate($angle)
79 {
80 if (self::DEBUG) echo __FUNCTION__ . "\n";
81
82 $a = deg2rad($angle);
83 $cos_a = cos($a);
84 $sin_a = sin($a);
85
86 $this->transform(
87 $cos_a, $sin_a,
88 -$sin_a, $cos_a,
89 0, 0
90 );
91 }
92
93 public function translate($x, $y)
94 {
95 if (self::DEBUG) echo __FUNCTION__ . "\n";
96
97 $this->transform(
98 1, 0,
99 0, 1,
100 $x, $y
101 );
102 }
103
104 public function transform($a, $b, $c, $d, $e, $f)
105 {
106 if (self::DEBUG) echo __FUNCTION__ . "\n";
107
108 $this->canvas->transform(array($a, $b, $c, $d, $e, $f));
109 }
110
111 public function beginPath()
112 {
113 if (self::DEBUG) echo __FUNCTION__ . "\n";
114 // TODO: Implement beginPath() method.
115 }
116
117 public function closePath()
118 {
119 if (self::DEBUG) echo __FUNCTION__ . "\n";
120 $this->canvas->closePath();
121 }
122
123 public function fillStroke()
124 {
125 if (self::DEBUG) echo __FUNCTION__ . "\n";
126 $this->canvas->fillStroke();
127 }
128
129 public function clip()
130 {
131 if (self::DEBUG) echo __FUNCTION__ . "\n";
132 $this->canvas->clip();
133 }
134
135 public function fillText($text, $x, $y, $maxWidth = null)
136 {
137 if (self::DEBUG) echo __FUNCTION__ . "\n";
138 $this->canvas->addText($x, $y, $this->style->fontSize, $text);
139 }
140
141 public function strokeText($text, $x, $y, $maxWidth = null)
142 {
143 if (self::DEBUG) echo __FUNCTION__ . "\n";
144 // TODO: Implement drawImage() method.
145 }
146
147 public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null)
148 {
149 if (self::DEBUG) echo __FUNCTION__ . "\n";
150
151 if (strpos($image, "data:") === 0) {
152 $data = substr($image, strpos($image, ";") + 1);
153 if (strpos($data, "base64") === 0) {
154 $data = base64_decode(substr($data, 7));
155 }
156 }
157 else {
158 $data = file_get_contents($image);
159 }
160
161 $image = tempnam("", "svg");
162 file_put_contents($image, $data);
163
164 $img = $this->image($image, $sx, $sy, $sw, $sh, "normal");
165
166
167 unlink($image);
168 }
169
170 public static function getimagesize($filename)
171 {
172 static $cache = array();
173
174 if (isset($cache[$filename])) {
175 return $cache[$filename];
176 }
177
178 list($width, $height, $type) = getimagesize($filename);
179
180 if ($width == null || $height == null) {
181 $data = file_get_contents($filename, null, null, 0, 26);
182
183 if (substr($data, 0, 2) === "BM") {
184 $meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data);
185 $width = (int)$meta['width'];
186 $height = (int)$meta['height'];
187 $type = IMAGETYPE_BMP;
188 }
189 }
190
191 return $cache[$filename] = array($width, $height, $type);
192 }
193
194 function image($img, $x, $y, $w, $h, $resolution = "normal")
195 {
196 list($width, $height, $type) = $this->getimagesize($img);
197
198 switch ($type) {
199 case IMAGETYPE_JPEG:
200 $this->canvas->addJpegFromFile($img, $x, $y - $h, $w, $h);
201 break;
202
203 case IMAGETYPE_GIF:
204 case IMAGETYPE_BMP:
205 // @todo use cache for BMP and GIF
206 $img = $this->_convert_gif_bmp_to_png($img, $type);
207
208 case IMAGETYPE_PNG:
209 $this->canvas->addPngFromFile($img, $x, $y - $h, $w, $h);
210 break;
211
212 default:
213 }
214 }
215
216 public function lineTo($x, $y)
217 {
218 if (self::DEBUG) echo __FUNCTION__ . "\n";
219 $this->canvas->lineTo($x, $y);
220 }
221
222 public function moveTo($x, $y)
223 {
224 if (self::DEBUG) echo __FUNCTION__ . "\n";
225 $this->canvas->moveTo($x, $y);
226 }
227
228 public function quadraticCurveTo($cpx, $cpy, $x, $y)
229 {
230 if (self::DEBUG) echo __FUNCTION__ . "\n";
231
232 // FIXME not accurate
233 $this->canvas->quadTo($cpx, $cpy, $x, $y);
234 }
235
236 public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y)
237 {
238 if (self::DEBUG) echo __FUNCTION__ . "\n";
239 $this->canvas->curveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y);
240 }
241
242 public function arcTo($x1, $y1, $x2, $y2, $radius)
243 {
244 if (self::DEBUG) echo __FUNCTION__ . "\n";
245 }
246
247 public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false)
248 {
249 if (self::DEBUG) echo __FUNCTION__ . "\n";
250 $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, $startAngle, $endAngle, false, false, false, true);
251 }
252
253 public function circle($x, $y, $radius)
254 {
255 if (self::DEBUG) echo __FUNCTION__ . "\n";
256 $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, 0, 360, true, false, false, false);
257 }
258
259 public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise)
260 {
261 if (self::DEBUG) echo __FUNCTION__ . "\n";
262 $this->canvas->ellipse($x, $y, $radiusX, $radiusY, 0, 8, 0, 360, false, false, false, false);
263 }
264
265 public function fillRect($x, $y, $w, $h)
266 {
267 if (self::DEBUG) echo __FUNCTION__ . "\n";
268 $this->rect($x, $y, $w, $h);
269 $this->fill();
270 }
271
272 public function rect($x, $y, $w, $h, $rx = 0, $ry = 0)
273 {
274 if (self::DEBUG) echo __FUNCTION__ . "\n";
275
276 $canvas = $this->canvas;
277
278 if ($rx <= 0.000001/* && $ry <= 0.000001*/) {
279 $canvas->rect($x, $y, $w, $h);
280
281 return;
282 }
283
284 /* Define a path for a rectangle with corners rounded by a given radius.
285 * Start from the lower left corner and proceed counterclockwise.
286 */
287 $this->moveTo($x + $rx, $y);
288
289 /* Start of the arc segment in the lower right corner */
290 $this->lineTo($x + $w - $rx, $y);
291
292 /* Arc segment in the lower right corner */
293 $this->arc($x + $w - $rx, $y + $rx, $rx, 270, 360);
294
295 /* Start of the arc segment in the upper right corner */
296 $this->lineTo($x + $w, $y + $h - $rx );
297
298 /* Arc segment in the upper right corner */
299 $this->arc($x + $w - $rx, $y + $h - $rx, $rx, 0, 90);
300
301 /* Start of the arc segment in the upper left corner */
302 $this->lineTo($x + $rx, $y + $h);
303
304 /* Arc segment in the upper left corner */
305 $this->arc($x + $rx, $y + $h - $rx, $rx, 90, 180);
306
307 /* Start of the arc segment in the lower left corner */
308 $this->lineTo($x , $y + $rx);
309
310 /* Arc segment in the lower left corner */
311 $this->arc($x + $rx, $y + $rx, $rx, 180, 270);
312 }
313
314 public function fill()
315 {
316 if (self::DEBUG) echo __FUNCTION__ . "\n";
317 $this->canvas->fill();
318 }
319
320 public function strokeRect($x, $y, $w, $h)
321 {
322 if (self::DEBUG) echo __FUNCTION__ . "\n";
323 $this->rect($x, $y, $w, $h);
324 $this->stroke();
325 }
326
327 public function stroke()
328 {
329 if (self::DEBUG) echo __FUNCTION__ . "\n";
330 $this->canvas->stroke();
331 }
332
333 public function endPath()
334 {
335 if (self::DEBUG) echo __FUNCTION__ . "\n";
336 $this->canvas->endPath();
337 }
338
339 public function measureText($text)
340 {
341 if (self::DEBUG) echo __FUNCTION__ . "\n";
342 $style = $this->getStyle();
343 $this->getFont($style->fontFamily, $style->fontStyle);
344
345 return $this->canvas->getTextWidth($this->getStyle()->fontSize, $text);
346 }
347
348 public function getStyle()
349 {
350 if (self::DEBUG) echo __FUNCTION__ . "\n";
351 return $this->style;
352 }
353
354 public function setStyle(Style $style)
355 {
356 if (self::DEBUG) echo __FUNCTION__ . "\n";
357
358 $this->style = $style;
359 $canvas = $this->canvas;
360
361 if ($stroke = $style->stroke) {
362 $canvas->setStrokeColor(array($stroke[0]/255, $stroke[1]/255, $stroke[2]/255), true);
363 }
364
365 if ($fill = $style->fill) {
366 $canvas->setColor(array($fill[0]/255, $fill[1]/255, $fill[2]/255), true);
367 }
368
369 if ($fillRule = strtolower($style->fillRule)) {
370 $canvas->setFillRule($fillRule);
371 }
372
373 $opacity = $style->opacity;
374 if ($opacity !== null && $opacity < 1.0) {
375 $canvas->setLineTransparency("Normal", $opacity);
376 $canvas->currentLineTransparency = null;
377
378 $canvas->setFillTransparency("Normal", $opacity);
379 $canvas->currentFillTransparency = null;
380 }
381 else {
382 $fillOpacity = $style->fillOpacity;
383 if ($fillOpacity !== null && $fillOpacity < 1.0) {
384 $canvas->setFillTransparency("Normal", $fillOpacity);
385 $canvas->currentFillTransparency = null;
386 }
387
388 $strokeOpacity = $style->strokeOpacity;
389 if ($strokeOpacity !== null && $strokeOpacity < 1.0) {
390 $canvas->setLineTransparency("Normal", $strokeOpacity);
391 $canvas->currentLineTransparency = null;
392 }
393 }
394
395 $canvas->setLineStyle(
396 $style->strokeWidth,
397 $style->strokeLinecap,
398 $style->strokeLinejoin
399 );
400
401 //$font = $this->getFont($style->fontFamily, $style->fontStyle);
402 //$canvas->setfont($font, $style->fontSize);
403 }
404
405 private function getFont($family, $style)
406 {
407 $map = array(
408 "serif" => "Times",
409 "sans-serif" => "Helvetica",
410 "fantasy" => "Symbol",
411 "cursive" => "Times",
412 "monospace" => "Courier",
413
414 "arial" => "Helvetica",
415 "verdana" => "Helvetica",
416 );
417
418 $family = strtolower($family);
419 if (isset($map[$family])) {
420 $family = $map[$family];
421 }
422
423 //return $this->canvas->load_font($family, "unicode", "fontstyle=$style");
424 }
425 }