web/lib/Zend/Barcode/Renderer/Svg.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/Zend/Barcode/Renderer/Svg.php	Fri Mar 11 15:05:35 2011 +0100
@@ -0,0 +1,382 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Barcode
+ * @subpackage Renderer
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: Image.php 20366 2010-01-18 03:56:52Z ralph $
+ */
+
+/** @see Zend_Barcode_Renderer_RendererAbstract*/
+require_once 'Zend/Barcode/Renderer/RendererAbstract.php';
+
+/**
+ * Class for rendering the barcode as svg
+ *
+ * @category   Zend
+ * @package    Zend_Barcode
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Barcode_Renderer_Svg extends Zend_Barcode_Renderer_RendererAbstract
+{
+
+    /**
+     * Resource for the image
+     * @var DOMDocument
+     */
+    protected $_resource = null;
+
+    /**
+     * Root element of the XML structure
+     * @var DOMElement
+     */
+    protected $_rootElement = null;
+
+    /**
+     * Height of the rendered image wanted by user
+     * @var integer
+     */
+    protected $_userHeight = 0;
+
+    /**
+     * Width of the rendered image wanted by user
+     * @var integer
+     */
+    protected $_userWidth = 0;
+
+    /**
+     * Set height of the result image
+     * @param null|integer $value
+     * @return Zend_Image_Barcode_Abstract
+     * @throw Zend_Image_Barcode_Exception
+     */
+    public function setHeight($value)
+    {
+        if (!is_numeric($value) || intval($value) < 0) {
+            require_once 'Zend/Barcode/Renderer/Exception.php';
+            throw new Zend_Barcode_Renderer_Exception(
+                'Svg height must be greater than or equals 0'
+            );
+        }
+        $this->_userHeight = intval($value);
+        return $this;
+    }
+
+    /**
+     * Get barcode height
+     *
+     * @return int
+     */
+    public function getHeight()
+    {
+        return $this->_userHeight;
+    }
+
+    /**
+     * Set barcode width
+     *
+     * @param mixed $value
+     * @return void
+     */
+    public function setWidth($value)
+    {
+        if (!is_numeric($value) || intval($value) < 0) {
+            require_once 'Zend/Barcode/Renderer/Exception.php';
+            throw new Zend_Barcode_Renderer_Exception(
+                'Svg width must be greater than or equals 0'
+            );
+        }
+        $this->_userWidth = intval($value);
+        return $this;
+    }
+
+    /**
+     * Get barcode width
+     *
+     * @return int
+     */
+    public function getWidth()
+    {
+        return $this->_userWidth;
+    }
+
+    /**
+     * Set an image resource to draw the barcode inside
+     *
+     * @param DOMDocument $value
+     * @return Zend_Barcode_Renderer
+     * @throw Zend_Barcode_Renderer_Exception
+     */
+    public function setResource($svg)
+    {
+        if (!$svg instanceof DOMDocument) {
+            require_once 'Zend/Barcode/Renderer/Exception.php';
+            throw new Zend_Barcode_Renderer_Exception(
+                'Invalid DOMDocument resource provided to setResource()'
+            );
+        }
+        $this->_resource = $svg;
+        return $this;
+    }
+
+    /**
+     * Initialize the image resource
+     *
+     * @return void
+     */
+    protected function _initRenderer()
+    {
+        $barcodeWidth  = $this->_barcode->getWidth(true);
+        $barcodeHeight = $this->_barcode->getHeight(true);
+
+        $backgroundColor = $this->_barcode->getBackgroundColor();
+        $imageBackgroundColor = 'rgb(' . implode(', ', array(($backgroundColor & 0xFF0000) >> 16,
+                                                             ($backgroundColor & 0x00FF00) >> 8,
+                                                             ($backgroundColor & 0x0000FF))) . ')';
+
+        $width = $barcodeWidth;
+        $height = $barcodeHeight;
+        if ($this->_userWidth && $this->_barcode->getType() != 'error') {
+            $width = $this->_userWidth;
+        }
+        if ($this->_userHeight && $this->_barcode->getType() != 'error') {
+            $height = $this->_userHeight;
+        }
+        if ($this->_resource === null) {
+            $this->_resource = new DOMDocument('1.0', 'utf-8');
+            $this->_resource->formatOutput = true;
+            $this->_rootElement = $this->_resource->createElement('svg');
+            $this->_rootElement->setAttribute('xmlns', "http://www.w3.org/2000/svg");
+            $this->_rootElement->setAttribute('version', '1.1');
+            $this->_rootElement->setAttribute('width', $width);
+            $this->_rootElement->setAttribute('height', $height);
+
+            $this->_appendRootElement('title',
+                                      array(),
+                                      "Barcode " . strtoupper($this->_barcode->getType()) . " " . $this->_barcode->getText());
+        } else {
+            $this->_readRootElement();
+            $width = $this->_rootElement->getAttribute('width');
+            $height = $this->_rootElement->getAttribute('height');
+        }
+        $this->_adjustPosition($height, $width);
+
+        $this->_appendRootElement('rect',
+                          array('x' => $this->_leftOffset,
+                                'y' => $this->_topOffset,
+                                'width' => ($this->_leftOffset + $barcodeWidth - 1),
+                                'height' => ($this->_topOffset + $barcodeHeight - 1),
+                                'fill' => $imageBackgroundColor));
+    }
+
+    protected function _readRootElement()
+    {
+        if ($this->_resource !== null) {
+            $this->_rootElement = $this->_resource->documentElement;
+        }
+    }
+
+    /**
+     * Append a new DOMElement to the root element
+     *
+     * @param string $tagName
+     * @param array $attributes
+     * @param string $textContent
+     */
+    protected function _appendRootElement($tagName, $attributes = array(), $textContent = null)
+    {
+        $newElement = $this->_createElement($tagName, $attributes, $textContent);
+        $this->_rootElement->appendChild($newElement);
+    }
+
+    /**
+     * Create DOMElement
+     *
+     * @param string $tagName
+     * @param array $attributes
+     * @param string $textContent
+     * @return DOMElement
+     */
+    protected function _createElement($tagName, $attributes = array(), $textContent = null)
+    {
+        $element = $this->_resource->createElement($tagName);
+        foreach ($attributes as $k =>$v) {
+            $element->setAttribute($k, $v);
+        }
+        if ($textContent !== null) {
+            $element->appendChild(new DOMText((string) $textContent));
+        }
+        return $element;
+    }
+
+    /**
+     * Check barcode parameters
+     *
+     * @return void
+     */
+    protected function _checkParams()
+    {
+        $this->_checkDimensions();
+    }
+
+    /**
+     * Check barcode dimensions
+     *
+     * @return void
+     */
+    protected function _checkDimensions()
+    {
+        if ($this->_resource !== null) {
+            $this->_readRootElement();
+            $height = (float) $this->_rootElement->getAttribute('height');
+            if ($height < $this->_barcode->getHeight(true)) {
+                require_once 'Zend/Barcode/Renderer/Exception.php';
+                throw new Zend_Barcode_Renderer_Exception(
+                    'Barcode is define outside the image (height)'
+                );
+            }
+        } else {
+            if ($this->_userHeight) {
+                $height = $this->_barcode->getHeight(true);
+                if ($this->_userHeight < $height) {
+                    require_once 'Zend/Barcode/Renderer/Exception.php';
+                    throw new Zend_Barcode_Renderer_Exception(sprintf(
+                        "Barcode is define outside the image (calculated: '%d', provided: '%d')",
+                        $height,
+                        $this->_userHeight
+                    ));
+                }
+            }
+        }
+        if ($this->_resource !== null) {
+            $this->_readRootElement();
+            $width = $this->_rootElement->getAttribute('width');
+            if ($width < $this->_barcode->getWidth(true)) {
+                require_once 'Zend/Barcode/Renderer/Exception.php';
+                throw new Zend_Barcode_Renderer_Exception(
+                    'Barcode is define outside the image (width)'
+                );
+            }
+        } else {
+            if ($this->_userWidth) {
+                $width = (float) $this->_barcode->getWidth(true);
+                if ($this->_userWidth < $width) {
+                    require_once 'Zend/Barcode/Renderer/Exception.php';
+                    throw new Zend_Barcode_Renderer_Exception(sprintf(
+                        "Barcode is define outside the image (calculated: '%d', provided: '%d')",
+                        $width,
+                        $this->_userWidth
+                    ));
+                }
+            }
+        }
+    }
+
+    /**
+     * Draw the barcode in the rendering resource
+     * @return mixed
+     */
+    public function draw()
+    {
+        parent::draw();
+        $this->_resource->appendChild($this->_rootElement);
+        return $this->_resource;
+    }
+
+    /**
+     * Draw and render the barcode with correct headers
+     *
+     * @return mixed
+     */
+    public function render()
+    {
+        $this->draw();
+        header("Content-Type: image/svg+xml");
+        echo $this->_resource->saveXML();
+    }
+
+    /**
+     * Draw a polygon in the svg resource
+     *
+     * @param array $points
+     * @param integer $color
+     * @param boolean $filled
+     */
+    protected function _drawPolygon($points, $color, $filled = true)
+    {
+        $color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16,
+                                              ($color & 0x00FF00) >> 8,
+                                              ($color & 0x0000FF))) . ')';
+        $orientation = $this->getBarcode()->getOrientation();
+        $newPoints = array(
+            $points[0][0] + $this->_leftOffset,
+            $points[0][1] + $this->_topOffset,
+            $points[1][0] + $this->_leftOffset,
+            $points[1][1] + $this->_topOffset,
+            $points[2][0] + $this->_leftOffset + cos(-$orientation),
+            $points[2][1] + $this->_topOffset - sin($orientation),
+            $points[3][0] + $this->_leftOffset + cos(-$orientation),
+            $points[3][1] + $this->_topOffset - sin($orientation),
+        );
+        $newPoints = implode(' ', $newPoints);
+        $attributes['points'] = $newPoints;
+        $attributes['fill'] = $color;
+        $this->_appendRootElement('polygon', $attributes);
+    }
+
+    /**
+     * Draw a polygon in the svg resource
+     *
+     * @param string $text
+     * @param float $size
+     * @param array $position
+     * @param string $font
+     * @param integer $color
+     * @param string $alignment
+     * @param float $orientation
+     */
+    protected function _drawText($text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0)
+    {
+        $color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16,
+                                              ($color & 0x00FF00) >> 8,
+                                              ($color & 0x0000FF))) . ')';
+        $attributes['x'] = $position[0] + $this->_leftOffset;
+        $attributes['y'] = $position[1] + $this->_topOffset;
+        //$attributes['font-family'] = $font;
+        $attributes['color'] = $color;
+        $attributes['font-size'] = $size * 1.2;
+        switch ($alignment) {
+            case 'left':
+                $textAnchor = 'start';
+                break;
+            case 'right':
+                $textAnchor = 'end';
+                break;
+            case 'center':
+            default:
+                $textAnchor = 'middle';
+        }
+        $attributes['style'] = 'text-anchor: ' . $textAnchor;
+        $attributes['transform'] = 'rotate('
+                                 . (- $orientation)
+                                 . ', '
+                                 . ($position[0] + $this->_leftOffset)
+                                 . ', ' . ($position[1] + $this->_topOffset)
+                                 . ')';
+        $this->_appendRootElement('text', $attributes, $text);
+    }
+}