web/enmi/Zend/Barcode/Renderer/Svg.php
changeset 19 1c2f13fd785c
parent 0 4eba9c11703f
equal deleted inserted replaced
18:bd595ad770fc 19:1c2f13fd785c
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Barcode
       
    17  * @subpackage Renderer
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: Image.php 20366 2010-01-18 03:56:52Z ralph $
       
    21  */
       
    22 
       
    23 /** @see Zend_Barcode_Renderer_RendererAbstract*/
       
    24 require_once 'Zend/Barcode/Renderer/RendererAbstract.php';
       
    25 
       
    26 /**
       
    27  * Class for rendering the barcode as svg
       
    28  *
       
    29  * @category   Zend
       
    30  * @package    Zend_Barcode
       
    31  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    32  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    33  */
       
    34 class Zend_Barcode_Renderer_Svg extends Zend_Barcode_Renderer_RendererAbstract
       
    35 {
       
    36 
       
    37     /**
       
    38      * Resource for the image
       
    39      * @var DOMDocument
       
    40      */
       
    41     protected $_resource = null;
       
    42 
       
    43     /**
       
    44      * Root element of the XML structure
       
    45      * @var DOMElement
       
    46      */
       
    47     protected $_rootElement = null;
       
    48 
       
    49     /**
       
    50      * Height of the rendered image wanted by user
       
    51      * @var integer
       
    52      */
       
    53     protected $_userHeight = 0;
       
    54 
       
    55     /**
       
    56      * Width of the rendered image wanted by user
       
    57      * @var integer
       
    58      */
       
    59     protected $_userWidth = 0;
       
    60 
       
    61     /**
       
    62      * Set height of the result image
       
    63      * @param null|integer $value
       
    64      * @return Zend_Image_Barcode_Abstract
       
    65      * @throw Zend_Image_Barcode_Exception
       
    66      */
       
    67     public function setHeight($value)
       
    68     {
       
    69         if (!is_numeric($value) || intval($value) < 0) {
       
    70             require_once 'Zend/Barcode/Renderer/Exception.php';
       
    71             throw new Zend_Barcode_Renderer_Exception(
       
    72                 'Svg height must be greater than or equals 0'
       
    73             );
       
    74         }
       
    75         $this->_userHeight = intval($value);
       
    76         return $this;
       
    77     }
       
    78 
       
    79     /**
       
    80      * Get barcode height
       
    81      *
       
    82      * @return int
       
    83      */
       
    84     public function getHeight()
       
    85     {
       
    86         return $this->_userHeight;
       
    87     }
       
    88 
       
    89     /**
       
    90      * Set barcode width
       
    91      *
       
    92      * @param mixed $value
       
    93      * @return void
       
    94      */
       
    95     public function setWidth($value)
       
    96     {
       
    97         if (!is_numeric($value) || intval($value) < 0) {
       
    98             require_once 'Zend/Barcode/Renderer/Exception.php';
       
    99             throw new Zend_Barcode_Renderer_Exception(
       
   100                 'Svg width must be greater than or equals 0'
       
   101             );
       
   102         }
       
   103         $this->_userWidth = intval($value);
       
   104         return $this;
       
   105     }
       
   106 
       
   107     /**
       
   108      * Get barcode width
       
   109      *
       
   110      * @return int
       
   111      */
       
   112     public function getWidth()
       
   113     {
       
   114         return $this->_userWidth;
       
   115     }
       
   116 
       
   117     /**
       
   118      * Set an image resource to draw the barcode inside
       
   119      *
       
   120      * @param DOMDocument $value
       
   121      * @return Zend_Barcode_Renderer
       
   122      * @throw Zend_Barcode_Renderer_Exception
       
   123      */
       
   124     public function setResource($svg)
       
   125     {
       
   126         if (!$svg instanceof DOMDocument) {
       
   127             require_once 'Zend/Barcode/Renderer/Exception.php';
       
   128             throw new Zend_Barcode_Renderer_Exception(
       
   129                 'Invalid DOMDocument resource provided to setResource()'
       
   130             );
       
   131         }
       
   132         $this->_resource = $svg;
       
   133         return $this;
       
   134     }
       
   135 
       
   136     /**
       
   137      * Initialize the image resource
       
   138      *
       
   139      * @return void
       
   140      */
       
   141     protected function _initRenderer()
       
   142     {
       
   143         $barcodeWidth  = $this->_barcode->getWidth(true);
       
   144         $barcodeHeight = $this->_barcode->getHeight(true);
       
   145 
       
   146         $backgroundColor = $this->_barcode->getBackgroundColor();
       
   147         $imageBackgroundColor = 'rgb(' . implode(', ', array(($backgroundColor & 0xFF0000) >> 16,
       
   148                                                              ($backgroundColor & 0x00FF00) >> 8,
       
   149                                                              ($backgroundColor & 0x0000FF))) . ')';
       
   150 
       
   151         $width = $barcodeWidth;
       
   152         $height = $barcodeHeight;
       
   153         if ($this->_userWidth && $this->_barcode->getType() != 'error') {
       
   154             $width = $this->_userWidth;
       
   155         }
       
   156         if ($this->_userHeight && $this->_barcode->getType() != 'error') {
       
   157             $height = $this->_userHeight;
       
   158         }
       
   159         if ($this->_resource === null) {
       
   160             $this->_resource = new DOMDocument('1.0', 'utf-8');
       
   161             $this->_resource->formatOutput = true;
       
   162             $this->_rootElement = $this->_resource->createElement('svg');
       
   163             $this->_rootElement->setAttribute('xmlns', "http://www.w3.org/2000/svg");
       
   164             $this->_rootElement->setAttribute('version', '1.1');
       
   165             $this->_rootElement->setAttribute('width', $width);
       
   166             $this->_rootElement->setAttribute('height', $height);
       
   167 
       
   168             $this->_appendRootElement('title',
       
   169                                       array(),
       
   170                                       "Barcode " . strtoupper($this->_barcode->getType()) . " " . $this->_barcode->getText());
       
   171         } else {
       
   172             $this->_readRootElement();
       
   173             $width = $this->_rootElement->getAttribute('width');
       
   174             $height = $this->_rootElement->getAttribute('height');
       
   175         }
       
   176         $this->_adjustPosition($height, $width);
       
   177 
       
   178         $this->_appendRootElement('rect',
       
   179                           array('x' => $this->_leftOffset,
       
   180                                 'y' => $this->_topOffset,
       
   181                                 'width' => ($this->_leftOffset + $barcodeWidth - 1),
       
   182                                 'height' => ($this->_topOffset + $barcodeHeight - 1),
       
   183                                 'fill' => $imageBackgroundColor));
       
   184     }
       
   185 
       
   186     protected function _readRootElement()
       
   187     {
       
   188         if ($this->_resource !== null) {
       
   189             $this->_rootElement = $this->_resource->documentElement;
       
   190         }
       
   191     }
       
   192 
       
   193     /**
       
   194      * Append a new DOMElement to the root element
       
   195      *
       
   196      * @param string $tagName
       
   197      * @param array $attributes
       
   198      * @param string $textContent
       
   199      */
       
   200     protected function _appendRootElement($tagName, $attributes = array(), $textContent = null)
       
   201     {
       
   202         $newElement = $this->_createElement($tagName, $attributes, $textContent);
       
   203         $this->_rootElement->appendChild($newElement);
       
   204     }
       
   205 
       
   206     /**
       
   207      * Create DOMElement
       
   208      *
       
   209      * @param string $tagName
       
   210      * @param array $attributes
       
   211      * @param string $textContent
       
   212      * @return DOMElement
       
   213      */
       
   214     protected function _createElement($tagName, $attributes = array(), $textContent = null)
       
   215     {
       
   216         $element = $this->_resource->createElement($tagName);
       
   217         foreach ($attributes as $k =>$v) {
       
   218             $element->setAttribute($k, $v);
       
   219         }
       
   220         if ($textContent !== null) {
       
   221             $element->appendChild(new DOMText((string) $textContent));
       
   222         }
       
   223         return $element;
       
   224     }
       
   225 
       
   226     /**
       
   227      * Check barcode parameters
       
   228      *
       
   229      * @return void
       
   230      */
       
   231     protected function _checkParams()
       
   232     {
       
   233         $this->_checkDimensions();
       
   234     }
       
   235 
       
   236     /**
       
   237      * Check barcode dimensions
       
   238      *
       
   239      * @return void
       
   240      */
       
   241     protected function _checkDimensions()
       
   242     {
       
   243         if ($this->_resource !== null) {
       
   244             $this->_readRootElement();
       
   245             $height = (float) $this->_rootElement->getAttribute('height');
       
   246             if ($height < $this->_barcode->getHeight(true)) {
       
   247                 require_once 'Zend/Barcode/Renderer/Exception.php';
       
   248                 throw new Zend_Barcode_Renderer_Exception(
       
   249                     'Barcode is define outside the image (height)'
       
   250                 );
       
   251             }
       
   252         } else {
       
   253             if ($this->_userHeight) {
       
   254                 $height = $this->_barcode->getHeight(true);
       
   255                 if ($this->_userHeight < $height) {
       
   256                     require_once 'Zend/Barcode/Renderer/Exception.php';
       
   257                     throw new Zend_Barcode_Renderer_Exception(sprintf(
       
   258                         "Barcode is define outside the image (calculated: '%d', provided: '%d')",
       
   259                         $height,
       
   260                         $this->_userHeight
       
   261                     ));
       
   262                 }
       
   263             }
       
   264         }
       
   265         if ($this->_resource !== null) {
       
   266             $this->_readRootElement();
       
   267             $width = $this->_rootElement->getAttribute('width');
       
   268             if ($width < $this->_barcode->getWidth(true)) {
       
   269                 require_once 'Zend/Barcode/Renderer/Exception.php';
       
   270                 throw new Zend_Barcode_Renderer_Exception(
       
   271                     'Barcode is define outside the image (width)'
       
   272                 );
       
   273             }
       
   274         } else {
       
   275             if ($this->_userWidth) {
       
   276                 $width = (float) $this->_barcode->getWidth(true);
       
   277                 if ($this->_userWidth < $width) {
       
   278                     require_once 'Zend/Barcode/Renderer/Exception.php';
       
   279                     throw new Zend_Barcode_Renderer_Exception(sprintf(
       
   280                         "Barcode is define outside the image (calculated: '%d', provided: '%d')",
       
   281                         $width,
       
   282                         $this->_userWidth
       
   283                     ));
       
   284                 }
       
   285             }
       
   286         }
       
   287     }
       
   288 
       
   289     /**
       
   290      * Draw the barcode in the rendering resource
       
   291      * @return mixed
       
   292      */
       
   293     public function draw()
       
   294     {
       
   295         parent::draw();
       
   296         $this->_resource->appendChild($this->_rootElement);
       
   297         return $this->_resource;
       
   298     }
       
   299 
       
   300     /**
       
   301      * Draw and render the barcode with correct headers
       
   302      *
       
   303      * @return mixed
       
   304      */
       
   305     public function render()
       
   306     {
       
   307         $this->draw();
       
   308         header("Content-Type: image/svg+xml");
       
   309         echo $this->_resource->saveXML();
       
   310     }
       
   311 
       
   312     /**
       
   313      * Draw a polygon in the svg resource
       
   314      *
       
   315      * @param array $points
       
   316      * @param integer $color
       
   317      * @param boolean $filled
       
   318      */
       
   319     protected function _drawPolygon($points, $color, $filled = true)
       
   320     {
       
   321         $color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16,
       
   322                                               ($color & 0x00FF00) >> 8,
       
   323                                               ($color & 0x0000FF))) . ')';
       
   324         $orientation = $this->getBarcode()->getOrientation();
       
   325         $newPoints = array(
       
   326             $points[0][0] + $this->_leftOffset,
       
   327             $points[0][1] + $this->_topOffset,
       
   328             $points[1][0] + $this->_leftOffset,
       
   329             $points[1][1] + $this->_topOffset,
       
   330             $points[2][0] + $this->_leftOffset + cos(-$orientation),
       
   331             $points[2][1] + $this->_topOffset - sin($orientation),
       
   332             $points[3][0] + $this->_leftOffset + cos(-$orientation),
       
   333             $points[3][1] + $this->_topOffset - sin($orientation),
       
   334         );
       
   335         $newPoints = implode(' ', $newPoints);
       
   336         $attributes['points'] = $newPoints;
       
   337         $attributes['fill'] = $color;
       
   338         $this->_appendRootElement('polygon', $attributes);
       
   339     }
       
   340 
       
   341     /**
       
   342      * Draw a polygon in the svg resource
       
   343      *
       
   344      * @param string $text
       
   345      * @param float $size
       
   346      * @param array $position
       
   347      * @param string $font
       
   348      * @param integer $color
       
   349      * @param string $alignment
       
   350      * @param float $orientation
       
   351      */
       
   352     protected function _drawText($text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0)
       
   353     {
       
   354         $color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16,
       
   355                                               ($color & 0x00FF00) >> 8,
       
   356                                               ($color & 0x0000FF))) . ')';
       
   357         $attributes['x'] = $position[0] + $this->_leftOffset;
       
   358         $attributes['y'] = $position[1] + $this->_topOffset;
       
   359         //$attributes['font-family'] = $font;
       
   360         $attributes['color'] = $color;
       
   361         $attributes['font-size'] = $size * 1.2;
       
   362         switch ($alignment) {
       
   363             case 'left':
       
   364                 $textAnchor = 'start';
       
   365                 break;
       
   366             case 'right':
       
   367                 $textAnchor = 'end';
       
   368                 break;
       
   369             case 'center':
       
   370             default:
       
   371                 $textAnchor = 'middle';
       
   372         }
       
   373         $attributes['style'] = 'text-anchor: ' . $textAnchor;
       
   374         $attributes['transform'] = 'rotate('
       
   375                                  . (- $orientation)
       
   376                                  . ', '
       
   377                                  . ($position[0] + $this->_leftOffset)
       
   378                                  . ', ' . ($position[1] + $this->_topOffset)
       
   379                                  . ')';
       
   380         $this->_appendRootElement('text', $attributes, $text);
       
   381     }
       
   382 }