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
14 class SurfaceCpdf
implements SurfaceInterface
27 public function __construct(Document
$doc, $canvas = null)
29 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
31 $dimensions = $doc->getDimensions();
32 $w = $dimensions["width"];
33 $h = $dimensions["height"];
36 $canvas = new CPdf(array(0, 0, $w, $h));
39 // Flip PDF coordinate system so that the origin is in
40 // the top left rather than the bottom left
41 $canvas->transform(array(
50 $this->canvas
= $canvas;
55 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
56 return $this->canvas
->output();
59 public function save()
61 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
62 $this->canvas
->save();
65 public function restore()
67 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
68 $this->canvas
->restore();
71 public function scale($x, $y)
73 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
75 $this->transform($x, 0, 0, $y, 0, 0);
78 public function rotate($angle)
80 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
93 public function translate($x, $y)
95 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
104 public function transform($a, $b, $c, $d, $e, $f)
106 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
108 $this->canvas
->transform(array($a, $b, $c, $d, $e, $f));
111 public function beginPath()
113 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
114 // TODO: Implement beginPath() method.
117 public function closePath()
119 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
120 $this->canvas
->closePath();
123 public function fillStroke()
125 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
126 $this->canvas
->fillStroke();
129 public function clip()
131 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
132 $this->canvas
->clip();
135 public function fillText($text, $x, $y, $maxWidth = null)
137 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
138 $this->canvas
->addText($x, $y, $this->style
->fontSize
, $text);
141 public function strokeText($text, $x, $y, $maxWidth = null)
143 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
144 // TODO: Implement drawImage() method.
147 public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null)
149 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
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));
158 $data = file_get_contents($image);
161 $image = tempnam("", "svg");
162 file_put_contents($image, $data);
164 $img = $this->image($image, $sx, $sy, $sw, $sh, "normal");
170 public static function getimagesize($filename)
172 static $cache = array();
174 if (isset($cache[$filename])) {
175 return $cache[$filename];
178 list($width, $height, $type) = getimagesize($filename);
180 if ($width == null ||
$height == null) {
181 $data = file_get_contents($filename, null, null, 0, 26);
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
;
191 return $cache[$filename] = array($width, $height, $type);
194 function image($img, $x, $y, $w, $h, $resolution = "normal")
196 list($width, $height, $type) = $this->getimagesize($img);
200 $this->canvas
->addJpegFromFile($img, $x, $y - $h, $w, $h);
205 // @todo use cache for BMP and GIF
206 $img = $this->_convert_gif_bmp_to_png($img, $type);
209 $this->canvas
->addPngFromFile($img, $x, $y - $h, $w, $h);
216 public function lineTo($x, $y)
218 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
219 $this->canvas
->lineTo($x, $y);
222 public function moveTo($x, $y)
224 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
225 $this->canvas
->moveTo($x, $y);
228 public function quadraticCurveTo($cpx, $cpy, $x, $y)
230 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
232 // FIXME not accurate
233 $this->canvas
->quadTo($cpx, $cpy, $x, $y);
236 public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y)
238 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
239 $this->canvas
->curveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y);
242 public function arcTo($x1, $y1, $x2, $y2, $radius)
244 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
247 public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false)
249 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
250 $this->canvas
->ellipse($x, $y, $radius, $radius, 0, 8, $startAngle, $endAngle, false, false, false, true);
253 public function circle($x, $y, $radius)
255 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
256 $this->canvas
->ellipse($x, $y, $radius, $radius, 0, 8, 0, 360, true, false, false, false);
259 public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise)
261 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
262 $this->canvas
->ellipse($x, $y, $radiusX, $radiusY, 0, 8, 0, 360, false, false, false, false);
265 public function fillRect($x, $y, $w, $h)
267 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
268 $this->rect($x, $y, $w, $h);
272 public function rect($x, $y, $w, $h, $rx = 0, $ry = 0)
274 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
276 $canvas = $this->canvas
;
278 if ($rx <= 0.000001/* && $ry <= 0.000001*/) {
279 $canvas->rect($x, $y, $w, $h);
284 /* Define a path for a rectangle with corners rounded by a given radius.
285 * Start from the lower left corner and proceed counterclockwise.
287 $this->moveTo($x +
$rx, $y);
289 /* Start of the arc segment in the lower right corner */
290 $this->lineTo($x +
$w - $rx, $y);
292 /* Arc segment in the lower right corner */
293 $this->arc($x +
$w - $rx, $y +
$rx, $rx, 270, 360);
295 /* Start of the arc segment in the upper right corner */
296 $this->lineTo($x +
$w, $y +
$h - $rx );
298 /* Arc segment in the upper right corner */
299 $this->arc($x +
$w - $rx, $y +
$h - $rx, $rx, 0, 90);
301 /* Start of the arc segment in the upper left corner */
302 $this->lineTo($x +
$rx, $y +
$h);
304 /* Arc segment in the upper left corner */
305 $this->arc($x +
$rx, $y +
$h - $rx, $rx, 90, 180);
307 /* Start of the arc segment in the lower left corner */
308 $this->lineTo($x , $y +
$rx);
310 /* Arc segment in the lower left corner */
311 $this->arc($x +
$rx, $y +
$rx, $rx, 180, 270);
314 public function fill()
316 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
317 $this->canvas
->fill();
320 public function strokeRect($x, $y, $w, $h)
322 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
323 $this->rect($x, $y, $w, $h);
327 public function stroke()
329 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
330 $this->canvas
->stroke();
333 public function endPath()
335 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
336 $this->canvas
->endPath();
339 public function measureText($text)
341 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
342 $style = $this->getStyle();
343 $this->getFont($style->fontFamily
, $style->fontStyle
);
345 return $this->canvas
->getTextWidth($this->getStyle()->fontSize
, $text);
348 public function getStyle()
350 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
354 public function setStyle(Style
$style)
356 if (self
::DEBUG
) echo __FUNCTION__
. "\n";
358 $this->style
= $style;
359 $canvas = $this->canvas
;
361 if ($stroke = $style->stroke
) {
362 $canvas->setStrokeColor(array($stroke[0]/255, $stroke[1]/255, $stroke[2]/255), true);
365 if ($fill = $style->fill
) {
366 $canvas->setColor(array($fill[0]/255, $fill[1]/255, $fill[2]/255), true);
369 if ($fillRule = strtolower($style->fillRule
)) {
370 $canvas->setFillRule($fillRule);
373 $opacity = $style->opacity
;
374 if ($opacity !== null && $opacity < 1.0) {
375 $canvas->setLineTransparency("Normal", $opacity);
376 $canvas->currentLineTransparency
= null;
378 $canvas->setFillTransparency("Normal", $opacity);
379 $canvas->currentFillTransparency
= null;
382 $fillOpacity = $style->fillOpacity
;
383 if ($fillOpacity !== null && $fillOpacity < 1.0) {
384 $canvas->setFillTransparency("Normal", $fillOpacity);
385 $canvas->currentFillTransparency
= null;
388 $strokeOpacity = $style->strokeOpacity
;
389 if ($strokeOpacity !== null && $strokeOpacity < 1.0) {
390 $canvas->setLineTransparency("Normal", $strokeOpacity);
391 $canvas->currentLineTransparency
= null;
395 $canvas->setLineStyle(
397 $style->strokeLinecap
,
398 $style->strokeLinejoin
401 //$font = $this->getFont($style->fontFamily, $style->fontStyle);
402 //$canvas->setfont($font, $style->fontSize);
405 private function getFont($family, $style)
409 "sans-serif" => "Helvetica",
410 "fantasy" => "Symbol",
411 "cursive" => "Times",
412 "monospace" => "Courier",
414 "arial" => "Helvetica",
415 "verdana" => "Helvetica",
418 $family = strtolower($family);
419 if (isset($map[$family])) {
420 $family = $map[$family];
423 //return $this->canvas->load_font($family, "unicode", "fontstyle=$style");