web/lib/Zend/Barcode/Object/ObjectAbstract.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     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 Object
       
    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: ObjectAbstract.php 23400 2010-11-19 17:18:31Z mikaelkael $
       
    21  */
       
    22 
       
    23 /**
       
    24  * Class for generate Barcode
       
    25  *
       
    26  * @category   Zend
       
    27  * @package    Zend_Barcode
       
    28  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    29  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    30  */
       
    31 abstract class Zend_Barcode_Object_ObjectAbstract
       
    32 {
       
    33     /**
       
    34      * Namespace of the barcode for autoloading
       
    35      * @var string
       
    36      */
       
    37     protected $_barcodeNamespace = 'Zend_Barcode_Object';
       
    38 
       
    39     /**
       
    40      * Set of drawing instructions
       
    41      * @var array
       
    42      */
       
    43     protected $_instructions = array();
       
    44 
       
    45     /**
       
    46      * Barcode type
       
    47      * @var string
       
    48      */
       
    49     protected $_type = null;
       
    50 
       
    51     /**
       
    52      * Height of the object
       
    53      * @var integer
       
    54      */
       
    55     protected $_height = null;
       
    56 
       
    57     /**
       
    58      * Width of the object
       
    59      * @var integer
       
    60      */
       
    61     protected $_width = null;
       
    62 
       
    63     /**
       
    64      * Height of the bar
       
    65      * @var integer
       
    66      */
       
    67     protected $_barHeight = 50;
       
    68 
       
    69     /**
       
    70      * Width of a thin bar
       
    71      * @var integer
       
    72      */
       
    73     protected $_barThinWidth = 1;
       
    74 
       
    75     /**
       
    76      * Width of a thick bar
       
    77      * @var integer
       
    78      */
       
    79     protected $_barThickWidth = 3;
       
    80 
       
    81     /**
       
    82      * Factor to multiply bar and font measure
       
    83      * (barHeight, barThinWidth, barThickWidth & fontSize)
       
    84      * @var integer
       
    85      */
       
    86     protected $_factor = 1;
       
    87 
       
    88     /**
       
    89      * Font and bars color of the object
       
    90      * @var integer
       
    91      */
       
    92     protected $_foreColor = 0x000000;
       
    93 
       
    94     /**
       
    95      * Background color of the object
       
    96      * @var integer
       
    97      */
       
    98     protected $_backgroundColor = 0xFFFFFF;
       
    99 
       
   100     /**
       
   101      * Activate/deactivate border of the object
       
   102      * @var boolean
       
   103      */
       
   104     protected $_withBorder = false;
       
   105 
       
   106     /**
       
   107      * Activate/deactivate drawing of quiet zones
       
   108      * @var boolean
       
   109      */
       
   110     protected $_withQuietZones = true;
       
   111 
       
   112     /**
       
   113      * Force quiet zones even if
       
   114      * @var boolean
       
   115      */
       
   116     protected $_mandatoryQuietZones = false;
       
   117 
       
   118     /**
       
   119      * Orientation of the barcode in degrees
       
   120      * @var float
       
   121      */
       
   122     protected $_orientation = 0;
       
   123 
       
   124     /**
       
   125      * Offset from the top the object
       
   126      * (calculated from the orientation)
       
   127      * @var integer
       
   128      */
       
   129     protected $_offsetTop = null;
       
   130 
       
   131     /**
       
   132      * Offset from the left the object
       
   133      * (calculated from the orientation)
       
   134      * @var integer
       
   135      */
       
   136     protected $_offsetLeft = null;
       
   137 
       
   138     /**
       
   139      * Text to display
       
   140      * @var string
       
   141      */
       
   142     protected $_text = null;
       
   143 
       
   144     /**
       
   145      * Display (or not) human readable text
       
   146      * @var boolean
       
   147      */
       
   148     protected $_drawText = true;
       
   149 
       
   150     /**
       
   151      * Adjust (or not) position of human readable characters with barcode
       
   152      * @var boolean
       
   153      */
       
   154     protected $_stretchText = false;
       
   155 
       
   156     /**
       
   157      * Font resource
       
   158      *  - integer (1 to 5): corresponds to GD included fonts
       
   159      *  - string: corresponds to path of a TTF font
       
   160      * @var integer|string
       
   161      */
       
   162     protected $_font = null;
       
   163 
       
   164     /**
       
   165      * Font size
       
   166      * @var float
       
   167      */
       
   168     protected $_fontSize = 10;
       
   169 
       
   170     /**
       
   171      * Drawing of checksum
       
   172      * @var boolean
       
   173      */
       
   174     protected $_withChecksum = false;
       
   175 
       
   176     /**
       
   177      * Drawing of checksum inside text
       
   178      * @var boolean
       
   179      */
       
   180     protected $_withChecksumInText = false;
       
   181 
       
   182     /**
       
   183      * Fix barcode length (numeric or string like 'even')
       
   184      * @var $_barcodeLength integer | string
       
   185      */
       
   186     protected $_barcodeLength = null;
       
   187 
       
   188     /**
       
   189      * Activate automatic addition of leading zeros
       
   190      * if barcode length is fixed
       
   191      * @var $_addLeadingZeros boolean
       
   192      */
       
   193     protected $_addLeadingZeros = true;
       
   194 
       
   195     /**
       
   196      * Activation of mandatory checksum
       
   197      * to deactivate unauthorized modification
       
   198      * @var $_mandatoryChecksum boolean
       
   199      */
       
   200     protected $_mandatoryChecksum = false;
       
   201 
       
   202     /**
       
   203      * Character used to substitute checksum character for validation
       
   204      * @var $_substituteChecksumCharacter mixed
       
   205      */
       
   206     protected $_substituteChecksumCharacter = 0;
       
   207 
       
   208     /**
       
   209      * TTF font name: can be set before instanciation of the object
       
   210      * @var string
       
   211      */
       
   212     protected static $_staticFont = null;
       
   213 
       
   214     /**
       
   215      * Constructor
       
   216      * @param array|Zend_Config $options
       
   217      * @return void
       
   218      */
       
   219     public function __construct($options = null)
       
   220     {
       
   221         $this->_getDefaultOptions();
       
   222         if (self::$_staticFont !== null) {
       
   223             $this->_font = self::$_staticFont;
       
   224         }
       
   225         if ($options instanceof Zend_Config) {
       
   226             $options = $options->toArray();
       
   227         }
       
   228         if (is_array($options)) {
       
   229             $this->setOptions($options);
       
   230         }
       
   231         $this->_type = strtolower(substr(get_class($this), strlen($this->_barcodeNamespace) + 1));
       
   232         if ($this->_mandatoryChecksum) {
       
   233             $this->_withChecksum = true;
       
   234             $this->_withChecksumInText = true;
       
   235         }
       
   236     }
       
   237 
       
   238     /**
       
   239      * Set default options for particular object
       
   240      * @return void
       
   241      */
       
   242     protected function _getDefaultOptions()
       
   243     {
       
   244     }
       
   245 
       
   246     /**
       
   247      * Set barcode state from options array
       
   248      * @param  array $options
       
   249      * @return Zend_Barcode_Object
       
   250      */
       
   251     public function setOptions($options)
       
   252     {
       
   253         foreach ($options as $key => $value) {
       
   254             $method = 'set' . $key;
       
   255             if (method_exists($this, $method)) {
       
   256                 $this->$method($value);
       
   257             }
       
   258         }
       
   259         return $this;
       
   260     }
       
   261 
       
   262     /**
       
   263      * Set barcode state from config object
       
   264      * @param Zend_Config $config
       
   265      * @return Zend_Barcode_Object
       
   266      */
       
   267     public function setConfig(Zend_Config $config)
       
   268     {
       
   269         return $this->setOptions($config->toArray());
       
   270     }
       
   271 
       
   272     /**
       
   273      * Set barcode namespace for autoloading
       
   274      *
       
   275      * @param string $namespace
       
   276      * @return Zend_Barcode_Object
       
   277      */
       
   278     public function setBarcodeNamespace($namespace)
       
   279     {
       
   280         $this->_barcodeNamespace = $namespace;
       
   281         return $this;
       
   282     }
       
   283 
       
   284     /**
       
   285      * Retrieve barcode namespace
       
   286      *
       
   287      * @return string
       
   288      */
       
   289     public function getBarcodeNamespace()
       
   290     {
       
   291         return $this->_barcodeNamespace;
       
   292     }
       
   293 
       
   294     /**
       
   295      * Retrieve type of barcode
       
   296      * @return string
       
   297      */
       
   298     public function getType()
       
   299     {
       
   300         return $this->_type;
       
   301     }
       
   302 
       
   303     /**
       
   304      * Set height of the barcode bar
       
   305      * @param integer $value
       
   306      * @return Zend_Barcode_Object
       
   307      * @throw Zend_Barcode_Object_Exception
       
   308      */
       
   309     public function setBarHeight($value)
       
   310     {
       
   311         if (intval($value) <= 0) {
       
   312             require_once 'Zend/Barcode/Object/Exception.php';
       
   313             throw new Zend_Barcode_Object_Exception(
       
   314                 'Bar height must be greater than 0'
       
   315             );
       
   316         }
       
   317         $this->_barHeight = intval($value);
       
   318         return $this;
       
   319     }
       
   320 
       
   321     /**
       
   322      * Get height of the barcode bar
       
   323      * @return integer
       
   324      */
       
   325     public function getBarHeight()
       
   326     {
       
   327         return $this->_barHeight;
       
   328     }
       
   329 
       
   330     /**
       
   331      * Set thickness of thin bar
       
   332      * @param integer $value
       
   333      * @return Zend_Barcode_Object
       
   334      * @throw Zend_Barcode_Object_Exception
       
   335      */
       
   336     public function setBarThinWidth($value)
       
   337     {
       
   338         if (intval($value) <= 0) {
       
   339             require_once 'Zend/Barcode/Object/Exception.php';
       
   340             throw new Zend_Barcode_Object_Exception(
       
   341                 'Bar width must be greater than 0'
       
   342             );
       
   343         }
       
   344         $this->_barThinWidth = intval($value);
       
   345         return $this;
       
   346     }
       
   347 
       
   348     /**
       
   349      * Get thickness of thin bar
       
   350      * @return integer
       
   351      */
       
   352     public function getBarThinWidth()
       
   353     {
       
   354         return $this->_barThinWidth;
       
   355     }
       
   356 
       
   357     /**
       
   358      * Set thickness of thick bar
       
   359      * @param integer $value
       
   360      * @return Zend_Barcode_Object
       
   361      * @throw Zend_Barcode_Object_Exception
       
   362      */
       
   363     public function setBarThickWidth($value)
       
   364     {
       
   365         if (intval($value) <= 0) {
       
   366             require_once 'Zend/Barcode/Object/Exception.php';
       
   367             throw new Zend_Barcode_Object_Exception(
       
   368                 'Bar width must be greater than 0'
       
   369             );
       
   370         }
       
   371         $this->_barThickWidth = intval($value);
       
   372         return $this;
       
   373     }
       
   374 
       
   375     /**
       
   376      * Get thickness of thick bar
       
   377      * @return integer
       
   378      */
       
   379     public function getBarThickWidth()
       
   380     {
       
   381         return $this->_barThickWidth;
       
   382     }
       
   383 
       
   384     /**
       
   385      * Set factor applying to
       
   386      * thinBarWidth - thickBarWidth - barHeight - fontSize
       
   387      * @param float $value
       
   388      * @return Zend_Barcode_Object
       
   389      * @throw Zend_Barcode_Object_Exception
       
   390      */
       
   391     public function setFactor($value)
       
   392     {
       
   393         if (floatval($value) <= 0) {
       
   394             require_once 'Zend/Barcode/Object/Exception.php';
       
   395             throw new Zend_Barcode_Object_Exception(
       
   396                 'Factor must be greater than 0'
       
   397             );
       
   398         }
       
   399         $this->_factor = floatval($value);
       
   400         return $this;
       
   401     }
       
   402 
       
   403     /**
       
   404      * Get factor applying to
       
   405      * thinBarWidth - thickBarWidth - barHeight - fontSize
       
   406      * @return integer
       
   407      */
       
   408     public function getFactor()
       
   409     {
       
   410         return $this->_factor;
       
   411     }
       
   412 
       
   413     /**
       
   414      * Set color of the barcode and text
       
   415      * @param string $value
       
   416      * @return Zend_Barcode_Object
       
   417      * @throw Zend_Barcode_Object_Exception
       
   418      */
       
   419     public function setForeColor($value)
       
   420     {
       
   421         if (preg_match('`\#[0-9A-F]{6}`', $value)) {
       
   422             $this->_foreColor = hexdec($value);
       
   423         } elseif (is_numeric($value) && $value >= 0 && $value <= 16777125) {
       
   424             $this->_foreColor = intval($value);
       
   425         } else {
       
   426             require_once 'Zend/Barcode/Object/Exception.php';
       
   427             throw new Zend_Barcode_Object_Exception(
       
   428                 'Text color must be set as #[0-9A-F]{6}'
       
   429             );
       
   430         }
       
   431         return $this;
       
   432     }
       
   433 
       
   434     /**
       
   435      * Retrieve color of the barcode and text
       
   436      * @return unknown
       
   437      */
       
   438     public function getForeColor()
       
   439     {
       
   440         return $this->_foreColor;
       
   441     }
       
   442 
       
   443     /**
       
   444      * Set the color of the background
       
   445      * @param integer $value
       
   446      * @return Zend_Barcode_Object
       
   447      * @throw Zend_Barcode_Object_Exception
       
   448      */
       
   449     public function setBackgroundColor($value)
       
   450     {
       
   451         if (preg_match('`\#[0-9A-F]{6}`', $value)) {
       
   452             $this->_backgroundColor = hexdec($value);
       
   453         } elseif (is_numeric($value) && $value >= 0 && $value <= 16777125) {
       
   454             $this->_backgroundColor = intval($value);
       
   455         } else {
       
   456             require_once 'Zend/Barcode/Object/Exception.php';
       
   457             throw new Zend_Barcode_Object_Exception(
       
   458                 'Background color must be set as #[0-9A-F]{6}'
       
   459             );
       
   460         }
       
   461         return $this;
       
   462     }
       
   463 
       
   464     /**
       
   465      * Retrieve background color of the image
       
   466      * @return integer
       
   467      */
       
   468     public function getBackgroundColor()
       
   469     {
       
   470         return $this->_backgroundColor;
       
   471     }
       
   472 
       
   473     /**
       
   474      * Activate/deactivate drawing of the bar
       
   475      * @param boolean $value
       
   476      * @return Zend_Barcode_Object
       
   477      */
       
   478     public function setWithBorder($value)
       
   479     {
       
   480         $this->_withBorder = (bool) $value;
       
   481         return $this;
       
   482     }
       
   483 
       
   484     /**
       
   485      * Retrieve if border are draw or not
       
   486      * @return boolean
       
   487      */
       
   488     public function getWithBorder()
       
   489     {
       
   490         return $this->_withBorder;
       
   491     }
       
   492 
       
   493     /**
       
   494      * Activate/deactivate drawing of the quiet zones
       
   495      * @param boolean $value
       
   496      * @return Zend_Barcode_Object
       
   497      */
       
   498     public function setWithQuietZones($value)
       
   499     {
       
   500         $this->_withQuietZones = (bool) $value;
       
   501         return $this;
       
   502     }
       
   503 
       
   504     /**
       
   505      * Retrieve if quiet zones are draw or not
       
   506      * @return boolean
       
   507      */
       
   508     public function getWithQuietZones()
       
   509     {
       
   510         return $this->_withQuietZones;
       
   511     }
       
   512 
       
   513     /**
       
   514      * Allow fast inversion of font/bars color and background color
       
   515      * @return Zend_Barcode_Object
       
   516      */
       
   517     public function setReverseColor()
       
   518     {
       
   519         $tmp                    = $this->_foreColor;
       
   520         $this->_foreColor       = $this->_backgroundColor;
       
   521         $this->_backgroundColor = $tmp;
       
   522         return $this;
       
   523     }
       
   524 
       
   525     /**
       
   526      * Set orientation of barcode and text
       
   527      * @param float $value
       
   528      * @return Zend_Barcode_Object
       
   529      * @throw Zend_Barcode_Object_Exception
       
   530      */
       
   531     public function setOrientation($value)
       
   532     {
       
   533         $this->_orientation = floatval($value) - floor(floatval($value) / 360) * 360;
       
   534         return $this;
       
   535     }
       
   536 
       
   537     /**
       
   538      * Retrieve orientation of barcode and text
       
   539      * @return float
       
   540      */
       
   541     public function getOrientation()
       
   542     {
       
   543         return $this->_orientation;
       
   544     }
       
   545 
       
   546     /**
       
   547      * Set text to encode
       
   548      * @param string $value
       
   549      * @return Zend_Barcode_Object
       
   550      */
       
   551     public function setText($value)
       
   552     {
       
   553         $this->_text = trim($value);
       
   554         return $this;
       
   555     }
       
   556 
       
   557     /**
       
   558      * Retrieve text to encode
       
   559      * @return string
       
   560      */
       
   561     public function getText()
       
   562     {
       
   563         $text = $this->_text;
       
   564         if ($this->_withChecksum) {
       
   565             $text .= $this->getChecksum($this->_text);
       
   566         }
       
   567         return $this->_addLeadingZeros($text);
       
   568     }
       
   569 
       
   570     /**
       
   571      * Automatically add leading zeros if barcode length is fixed
       
   572      * @param string $text
       
   573      * @param boolean $withoutChecksum
       
   574      */
       
   575     protected function _addLeadingZeros($text, $withoutChecksum = false)
       
   576     {
       
   577         if ($this->_barcodeLength && $this->_addLeadingZeros) {
       
   578             $omitChecksum = (int) ($this->_withChecksum && $withoutChecksum);
       
   579             if (is_int($this->_barcodeLength)) {
       
   580                 $length = $this->_barcodeLength - $omitChecksum;
       
   581                 if (strlen($text) < $length) {
       
   582                     $text = str_repeat('0', $length - strlen($text)) . $text;
       
   583                 }
       
   584             } else {
       
   585                 if ($this->_barcodeLength == 'even') {
       
   586                     $text = ((strlen($text) - $omitChecksum) % 2 ? '0' . $text : $text);
       
   587                 }
       
   588             }
       
   589         }
       
   590         return $text;
       
   591     }
       
   592 
       
   593     /**
       
   594      * Retrieve text to encode
       
   595      * @return string
       
   596      */
       
   597     public function getRawText()
       
   598     {
       
   599         return $this->_text;
       
   600     }
       
   601 
       
   602     /**
       
   603      * Retrieve text to display
       
   604      * @return string
       
   605      */
       
   606     public function getTextToDisplay()
       
   607     {
       
   608         if ($this->_withChecksumInText) {
       
   609             return $this->getText();
       
   610         } else {
       
   611             return $this->_addLeadingZeros($this->_text, true);
       
   612         }
       
   613     }
       
   614 
       
   615     /**
       
   616      * Activate/deactivate drawing of text to encode
       
   617      * @param boolean $value
       
   618      * @return Zend_Barcode_Object
       
   619      */
       
   620     public function setDrawText($value)
       
   621     {
       
   622         $this->_drawText = (bool) $value;
       
   623         return $this;
       
   624     }
       
   625 
       
   626     /**
       
   627      * Retrieve if drawing of text to encode is enabled
       
   628      * @return boolean
       
   629      */
       
   630     public function getDrawText()
       
   631     {
       
   632         return $this->_drawText;
       
   633     }
       
   634 
       
   635     /**
       
   636      * Activate/deactivate the adjustment of the position
       
   637      * of the characters to the position of the bars
       
   638      * @param boolean $value
       
   639      * @return Zend_Barcode_Object
       
   640      * @throw Zend_Barcode_Object_Exception
       
   641      */
       
   642     public function setStretchText($value)
       
   643     {
       
   644         $this->_stretchText = (bool) $value;
       
   645         return $this;
       
   646     }
       
   647 
       
   648     /**
       
   649      * Retrieve if the adjustment of the position of the characters
       
   650      * to the position of the bars is enabled
       
   651      * @return boolean
       
   652      */
       
   653     public function getStretchText()
       
   654     {
       
   655         return $this->_stretchText;
       
   656     }
       
   657 
       
   658     /**
       
   659      * Activate/deactivate the automatic generation
       
   660      * of the checksum character
       
   661      * added to the barcode text
       
   662      * @param boolean $value
       
   663      * @return Zend_Barcode_Object
       
   664      */
       
   665     public function setWithChecksum($value)
       
   666     {
       
   667         if (!$this->_mandatoryChecksum) {
       
   668             $this->_withChecksum = (bool) $value;
       
   669         }
       
   670         return $this;
       
   671     }
       
   672 
       
   673     /**
       
   674      * Retrieve if the checksum character is automatically
       
   675      * added to the barcode text
       
   676      * @return boolean
       
   677      */
       
   678     public function getWithChecksum()
       
   679     {
       
   680         return $this->_withChecksum;
       
   681     }
       
   682 
       
   683     /**
       
   684      * Activate/deactivate the automatic generation
       
   685      * of the checksum character
       
   686      * added to the barcode text
       
   687      * @param boolean $value
       
   688      * @return Zend_Barcode_Object
       
   689      * @throw Zend_Barcode_Object_Exception
       
   690      */
       
   691     public function setWithChecksumInText($value)
       
   692     {
       
   693         if (!$this->_mandatoryChecksum) {
       
   694             $this->_withChecksumInText = (bool) $value;
       
   695         }
       
   696         return $this;
       
   697     }
       
   698 
       
   699     /**
       
   700      * Retrieve if the checksum character is automatically
       
   701      * added to the barcode text
       
   702      * @return boolean
       
   703      */
       
   704     public function getWithChecksumInText()
       
   705     {
       
   706         return $this->_withChecksumInText;
       
   707     }
       
   708 
       
   709     /**
       
   710      * Set the font for all instances of barcode
       
   711      * @param string $font
       
   712      * @return void
       
   713      */
       
   714     public static function setBarcodeFont($font)
       
   715     {
       
   716         if (is_string($font) || (is_int($font) && $font >= 1 && $font <= 5)) {
       
   717             self::$_staticFont = $font;
       
   718         }
       
   719     }
       
   720 
       
   721     /**
       
   722      * Set the font:
       
   723      *  - if integer between 1 and 5, use gd built-in fonts
       
   724      *  - if string, $value is assumed to be the path to a TTF font
       
   725      * @param integer|string $value
       
   726      * @return Zend_Barcode_Object
       
   727      * @throw Zend_Barcode_Object_Exception
       
   728      */
       
   729     public function setFont($value)
       
   730     {
       
   731         if (is_int($value) && $value >= 1 && $value <= 5) {
       
   732             if (!extension_loaded('gd')) {
       
   733                 require_once 'Zend/Barcode/Object/Exception.php';
       
   734                 throw new Zend_Barcode_Object_Exception(
       
   735                     'GD extension is required to use numeric font'
       
   736                 );
       
   737             }
       
   738 
       
   739             // Case of numeric font with GD
       
   740             $this->_font = $value;
       
   741 
       
   742             // In this case font size is given by:
       
   743             $this->_fontSize = imagefontheight($value);
       
   744         } elseif (is_string($value)) {
       
   745             $this->_font = $value;
       
   746         } else {
       
   747             require_once 'Zend/Barcode/Object/Exception.php';
       
   748             throw new Zend_Barcode_Object_Exception(sprintf(
       
   749                 'Invalid font "%s" provided to setFont()',
       
   750                 $value
       
   751             ));
       
   752         }
       
   753         return $this;
       
   754     }
       
   755 
       
   756     /**
       
   757      * Retrieve the font
       
   758      * @return integer|string
       
   759      */
       
   760     public function getFont()
       
   761     {
       
   762         return $this->_font;
       
   763     }
       
   764 
       
   765     /**
       
   766      * Set the size of the font in case of TTF
       
   767      * @param float $value
       
   768      * @return Zend_Barcode_Object
       
   769      * @throw Zend_Barcode_Object_Exception
       
   770      */
       
   771     public function setFontSize($value)
       
   772     {
       
   773         if (is_numeric($this->_font)) {
       
   774             // Case of numeric font with GD
       
   775             return $this;
       
   776         }
       
   777 
       
   778         if (!is_numeric($value)) {
       
   779             require_once 'Zend/Barcode/Object/Exception.php';
       
   780             throw new Zend_Barcode_Object_Exception(
       
   781                 'Font size must be a numeric value'
       
   782             );
       
   783         }
       
   784 
       
   785         $this->_fontSize = $value;
       
   786         return $this;
       
   787     }
       
   788 
       
   789     /**
       
   790      * Retrieve the size of the font in case of TTF
       
   791      * @return float
       
   792      */
       
   793     public function getFontSize()
       
   794     {
       
   795         return $this->_fontSize;
       
   796     }
       
   797 
       
   798     /**
       
   799      * Quiet zone before first bar
       
   800      * and after the last bar
       
   801      * @return integer
       
   802      */
       
   803     public function getQuietZone()
       
   804     {
       
   805         if ($this->_withQuietZones || $this->_mandatoryQuietZones) {
       
   806             return 10 * $this->_barThinWidth * $this->_factor;
       
   807         } else {
       
   808             return 0;
       
   809         }
       
   810     }
       
   811 
       
   812     /**
       
   813      * Add an instruction in the array of instructions
       
   814      * @param array $instruction
       
   815      */
       
   816     protected function _addInstruction(array $instruction)
       
   817     {
       
   818         $this->_instructions[] = $instruction;
       
   819     }
       
   820 
       
   821     /**
       
   822      * Retrieve the set of drawing instructions
       
   823      * @return array
       
   824      */
       
   825     public function getInstructions()
       
   826     {
       
   827         return $this->_instructions;
       
   828     }
       
   829 
       
   830     /**
       
   831      * Add a polygon drawing instruction in the set of instructions
       
   832      * @param array $points
       
   833      * @param integer $color
       
   834      * @param boolean $filled
       
   835      */
       
   836     protected function _addPolygon(array $points, $color = null, $filled = true)
       
   837     {
       
   838         if ($color === null) {
       
   839             $color = $this->_foreColor;
       
   840         }
       
   841         $this->_addInstruction(array(
       
   842             'type'   => 'polygon',
       
   843             'points' => $points,
       
   844             'color'  => $color,
       
   845             'filled' => $filled,
       
   846         ));
       
   847     }
       
   848 
       
   849     /**
       
   850      * Add a text drawing instruction in the set of instructions
       
   851      * @param string $text
       
   852      * @param float $size
       
   853      * @param array $position
       
   854      * @param string $font
       
   855      * @param integer $color
       
   856      * @param string $alignment
       
   857      * @param float $orientation
       
   858      */
       
   859     protected function _addText(
       
   860         $text,
       
   861         $size,
       
   862         $position,
       
   863         $font,
       
   864         $color,
       
   865         $alignment = 'center',
       
   866         $orientation = 0
       
   867     ) {
       
   868         if ($color === null) {
       
   869             $color = $this->_foreColor;
       
   870         }
       
   871         $this->_addInstruction(array(
       
   872             'type'        => 'text',
       
   873             'text'        => $text,
       
   874             'size'        => $size,
       
   875             'position'    => $position,
       
   876             'font'        => $font,
       
   877             'color'       => $color,
       
   878             'alignment'   => $alignment,
       
   879             'orientation' => $orientation,
       
   880         ));
       
   881     }
       
   882 
       
   883     /**
       
   884      * Checking of parameters after all settings
       
   885      * @return void
       
   886      */
       
   887     public function checkParams()
       
   888     {
       
   889         $this->_checkText();
       
   890         $this->_checkFontAndOrientation();
       
   891         $this->_checkParams();
       
   892         return true;
       
   893     }
       
   894 
       
   895     /**
       
   896      * Check if a text is really provided to barcode
       
   897      * @return void
       
   898      * @throw Zend_Barcode_Object_Exception
       
   899      */
       
   900     protected function _checkText($value = null)
       
   901     {
       
   902         if ($value === null) {
       
   903             $value = $this->_text;
       
   904         }
       
   905         if (!strlen($value)) {
       
   906             require_once 'Zend/Barcode/Object/Exception.php';
       
   907             throw new Zend_Barcode_Object_Exception(
       
   908                 'A text must be provide to Barcode before drawing'
       
   909             );
       
   910         }
       
   911         $this->validateText($value);
       
   912     }
       
   913 
       
   914     /**
       
   915      * Check the ratio between the thick and the thin bar
       
   916      * @param integer $min
       
   917      * @param integer $max
       
   918      * @return void
       
   919      * @throw Zend_Barcode_Object_Exception
       
   920      */
       
   921     protected function _checkRatio($min = 2, $max = 3)
       
   922     {
       
   923         $ratio = $this->_barThickWidth / $this->_barThinWidth;
       
   924         if (!($ratio >= $min && $ratio <= $max)) {
       
   925             require_once 'Zend/Barcode/Object/Exception.php';
       
   926             throw new Zend_Barcode_Object_Exception(sprintf(
       
   927                 'Ratio thick/thin bar must be between %0.1f and %0.1f (actual %0.3f)',
       
   928                 $min,
       
   929                 $max,
       
   930                 $ratio
       
   931             ));
       
   932         }
       
   933     }
       
   934 
       
   935     /**
       
   936      * Drawing with an angle is just allow TTF font
       
   937      * @return void
       
   938      * @throw Zend_Barcode_Object_Exception
       
   939      */
       
   940     protected function _checkFontAndOrientation()
       
   941     {
       
   942         if (is_numeric($this->_font) && $this->_orientation != 0) {
       
   943             require_once 'Zend/Barcode/Object/Exception.php';
       
   944             throw new Zend_Barcode_Object_Exception(
       
   945                 'Only drawing with TTF font allow orientation of the barcode.'
       
   946             );
       
   947         }
       
   948     }
       
   949 
       
   950     /**
       
   951      * Width of the result image
       
   952      * (before any rotation)
       
   953      * @return integer
       
   954      */
       
   955     protected function _calculateWidth()
       
   956     {
       
   957         return (int) $this->_withBorder
       
   958             + $this->_calculateBarcodeWidth()
       
   959             + (int) $this->_withBorder;
       
   960     }
       
   961 
       
   962     /**
       
   963      * Calculate the width of the barcode
       
   964      * @return integer
       
   965      */
       
   966     abstract protected function _calculateBarcodeWidth();
       
   967 
       
   968     /**
       
   969      * Height of the result object
       
   970      * @return integer
       
   971      */
       
   972     protected function _calculateHeight()
       
   973     {
       
   974         return (int) $this->_withBorder * 2
       
   975             + $this->_calculateBarcodeHeight()
       
   976             + (int) $this->_withBorder * 2;
       
   977     }
       
   978 
       
   979     /**
       
   980      * Height of the barcode
       
   981      * @return integer
       
   982      */
       
   983     protected function _calculateBarcodeHeight()
       
   984     {
       
   985         $textHeight = 0;
       
   986         $extraHeight = 0;
       
   987         if ($this->_drawText) {
       
   988             $textHeight += $this->_fontSize;
       
   989             $extraHeight = 2;
       
   990         }
       
   991         return ($this->_barHeight + $textHeight) * $this->_factor + $extraHeight;
       
   992     }
       
   993 
       
   994     /**
       
   995      * Get height of the result object
       
   996      * @return integer
       
   997      */
       
   998     public function getHeight($recalculate = false)
       
   999     {
       
  1000         if ($this->_height === null || $recalculate) {
       
  1001             $this->_height =
       
  1002                 abs($this->_calculateHeight() * cos($this->_orientation / 180 * pi()))
       
  1003                 + abs($this->_calculateWidth() * sin($this->_orientation / 180 * pi()));
       
  1004         }
       
  1005         return $this->_height;
       
  1006     }
       
  1007 
       
  1008     /**
       
  1009      * Get width of the result object
       
  1010      * @return integer
       
  1011      */
       
  1012     public function getWidth($recalculate = false)
       
  1013     {
       
  1014         if ($this->_width === null || $recalculate) {
       
  1015             $this->_width =
       
  1016                 abs($this->_calculateWidth() * cos($this->_orientation / 180 * pi()))
       
  1017                 + abs($this->_calculateHeight() * sin($this->_orientation / 180 * pi()));
       
  1018         }
       
  1019         return $this->_width;
       
  1020     }
       
  1021 
       
  1022     /**
       
  1023      * Calculate the offset from the left of the object
       
  1024      * if an orientation is activated
       
  1025      * @param boolean $recalculate
       
  1026      * @return float
       
  1027      */
       
  1028     public function getOffsetLeft($recalculate = false)
       
  1029     {
       
  1030         if ($this->_offsetLeft === null || $recalculate) {
       
  1031             $this->_offsetLeft = - min(array(
       
  1032                 0 * cos(
       
  1033                         $this->_orientation / 180 * pi()) - 0 * sin(
       
  1034                         $this->_orientation / 180 * pi()),
       
  1035                 0 * cos(
       
  1036                         $this->_orientation / 180 * pi()) - $this->_calculateBarcodeHeight() * sin(
       
  1037                         $this->_orientation / 180 * pi()),
       
  1038                 $this->_calculateBarcodeWidth() * cos(
       
  1039                         $this->_orientation / 180 * pi()) - $this->_calculateBarcodeHeight() * sin(
       
  1040                         $this->_orientation / 180 * pi()),
       
  1041                 $this->_calculateBarcodeWidth() * cos(
       
  1042                         $this->_orientation / 180 * pi()) - 0 * sin(
       
  1043                         $this->_orientation / 180 * pi()),
       
  1044             ));
       
  1045         }
       
  1046         return $this->_offsetLeft;
       
  1047     }
       
  1048 
       
  1049     /**
       
  1050      * Calculate the offset from the top of the object
       
  1051      * if an orientation is activated
       
  1052      * @param boolean $recalculate
       
  1053      * @return float
       
  1054      */
       
  1055     public function getOffsetTop($recalculate = false)
       
  1056     {
       
  1057         if ($this->_offsetTop === null || $recalculate) {
       
  1058             $this->_offsetTop = - min(array(
       
  1059                 0 * cos(
       
  1060                         $this->_orientation / 180 * pi()) + 0 * sin(
       
  1061                         $this->_orientation / 180 * pi()),
       
  1062                 $this->_calculateBarcodeHeight() * cos(
       
  1063                         $this->_orientation / 180 * pi()) + 0 * sin(
       
  1064                         $this->_orientation / 180 * pi()),
       
  1065                 $this->_calculateBarcodeHeight() * cos(
       
  1066                         $this->_orientation / 180 * pi()) + $this->_calculateBarcodeWidth() * sin(
       
  1067                         $this->_orientation / 180 * pi()),
       
  1068                 0 * cos(
       
  1069                         $this->_orientation / 180 * pi()) + $this->_calculateBarcodeWidth() * sin(
       
  1070                         $this->_orientation / 180 * pi()),
       
  1071             ));
       
  1072         }
       
  1073         return $this->_offsetTop;
       
  1074     }
       
  1075 
       
  1076     /**
       
  1077      * Apply rotation on a point in X/Y dimensions
       
  1078      * @param float $x1     x-position before rotation
       
  1079      * @param float $y1     y-position before rotation
       
  1080      * @return array        Array of two elements corresponding to the new XY point
       
  1081      */
       
  1082     protected function _rotate($x1, $y1)
       
  1083     {
       
  1084         $x2 = $x1 * cos($this->_orientation / 180 * pi())
       
  1085             - $y1 * sin($this->_orientation / 180 * pi())
       
  1086             + $this->getOffsetLeft();
       
  1087         $y2 = $y1 * cos($this->_orientation / 180 * pi())
       
  1088             + $x1 * sin($this->_orientation / 180 * pi())
       
  1089             + $this->getOffsetTop();
       
  1090         return array(intval($x2) , intval($y2));
       
  1091     }
       
  1092 
       
  1093     /**
       
  1094      * Complete drawing of the barcode
       
  1095      * @return array Table of instructions
       
  1096      */
       
  1097     public function draw()
       
  1098     {
       
  1099         $this->checkParams();
       
  1100         $this->_drawBarcode();
       
  1101         $this->_drawBorder();
       
  1102         $this->_drawText();
       
  1103         return $this->getInstructions();
       
  1104     }
       
  1105 
       
  1106     /**
       
  1107      * Draw the barcode
       
  1108      * @return void
       
  1109      */
       
  1110     protected function _drawBarcode()
       
  1111     {
       
  1112         $barcodeTable = $this->_prepareBarcode();
       
  1113 
       
  1114         $this->_preDrawBarcode();
       
  1115 
       
  1116         $xpos = (int) $this->_withBorder;
       
  1117         $ypos = (int) $this->_withBorder;
       
  1118 
       
  1119         $point1 = $this->_rotate(0, 0);
       
  1120         $point2 = $this->_rotate(0, $this->_calculateHeight() - 1);
       
  1121         $point3 = $this->_rotate(
       
  1122             $this->_calculateWidth() - 1,
       
  1123             $this->_calculateHeight() - 1
       
  1124         );
       
  1125         $point4 = $this->_rotate($this->_calculateWidth() - 1, 0);
       
  1126 
       
  1127         $this->_addPolygon(array(
       
  1128             $point1,
       
  1129             $point2,
       
  1130             $point3,
       
  1131             $point4
       
  1132         ), $this->_backgroundColor);
       
  1133 
       
  1134         $xpos     += $this->getQuietZone();
       
  1135         $barLength = $this->_barHeight * $this->_factor;
       
  1136 
       
  1137         foreach ($barcodeTable as $bar) {
       
  1138             $width = $bar[1] * $this->_factor;
       
  1139             if ($bar[0]) {
       
  1140                 $point1 = $this->_rotate($xpos, $ypos + $bar[2] * $barLength);
       
  1141                 $point2 = $this->_rotate($xpos, $ypos + $bar[3] * $barLength);
       
  1142                 $point3 = $this->_rotate(
       
  1143                     $xpos + $width - 1,
       
  1144                     $ypos + $bar[3] * $barLength
       
  1145                 );
       
  1146                 $point4 = $this->_rotate(
       
  1147                     $xpos + $width - 1,
       
  1148                     $ypos + $bar[2] * $barLength
       
  1149                 );
       
  1150                 $this->_addPolygon(array(
       
  1151                     $point1,
       
  1152                     $point2,
       
  1153                     $point3,
       
  1154                     $point4,
       
  1155                 ));
       
  1156             }
       
  1157             $xpos += $width;
       
  1158         }
       
  1159 
       
  1160         $this->_postDrawBarcode();
       
  1161     }
       
  1162 
       
  1163     /**
       
  1164      * Partial function to draw border
       
  1165      * @return void
       
  1166      */
       
  1167     protected function _drawBorder()
       
  1168     {
       
  1169         if ($this->_withBorder) {
       
  1170             $point1 = $this->_rotate(0, 0);
       
  1171             $point2 = $this->_rotate($this->_calculateWidth() - 1, 0);
       
  1172             $point3 = $this->_rotate(
       
  1173                 $this->_calculateWidth() - 1,
       
  1174                 $this->_calculateHeight() - 1
       
  1175             );
       
  1176             $point4 = $this->_rotate(0, $this->_calculateHeight() - 1);
       
  1177             $this->_addPolygon(array(
       
  1178                 $point1,
       
  1179                 $point2,
       
  1180                 $point3,
       
  1181                 $point4,
       
  1182                 $point1,
       
  1183             ), $this->_foreColor, false);
       
  1184         }
       
  1185     }
       
  1186 
       
  1187     /**
       
  1188      * Partial function to draw text
       
  1189      * @return void
       
  1190      */
       
  1191     protected function _drawText()
       
  1192     {
       
  1193         if ($this->_drawText) {
       
  1194             $text = $this->getTextToDisplay();
       
  1195             if ($this->_stretchText) {
       
  1196                 $textLength = strlen($text);
       
  1197                 $space      = ($this->_calculateWidth() - 2 * $this->getQuietZone()) / $textLength;
       
  1198                 for ($i = 0; $i < $textLength; $i ++) {
       
  1199                     $leftPosition = $this->getQuietZone() + $space * ($i + 0.5);
       
  1200                     $this->_addText(
       
  1201                         $text{$i},
       
  1202                         $this->_fontSize * $this->_factor,
       
  1203                         $this->_rotate(
       
  1204                             $leftPosition,
       
  1205                             (int) $this->_withBorder * 2
       
  1206                                 + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1
       
  1207                         ),
       
  1208                         $this->_font,
       
  1209                         $this->_foreColor,
       
  1210                         'center',
       
  1211                         - $this->_orientation
       
  1212                     );
       
  1213                 }
       
  1214             } else {
       
  1215                 $this->_addText(
       
  1216                     $text,
       
  1217                     $this->_fontSize * $this->_factor,
       
  1218                     $this->_rotate(
       
  1219                         $this->_calculateWidth() / 2,
       
  1220                         (int) $this->_withBorder * 2
       
  1221                             + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1
       
  1222                     ),
       
  1223                     $this->_font,
       
  1224                     $this->_foreColor,
       
  1225                     'center',
       
  1226                     - $this->_orientation
       
  1227                 );
       
  1228             }
       
  1229         }
       
  1230     }
       
  1231 
       
  1232     /**
       
  1233      * Check for invalid characters
       
  1234      * @param   string $value    Text to be ckecked
       
  1235      * @return void
       
  1236      */
       
  1237     public function validateText($value)
       
  1238     {
       
  1239         $this->_validateText($value);
       
  1240     }
       
  1241 
       
  1242     /**
       
  1243      * Standard validation for most of barcode objects
       
  1244      * @param string $value
       
  1245      * @param array  $options
       
  1246      */
       
  1247     protected function _validateText($value, $options = array())
       
  1248     {
       
  1249         $validatorName = (isset($options['validator'])) ? $options['validator'] : $this->getType();
       
  1250 
       
  1251         $validator = new Zend_Validate_Barcode(array(
       
  1252             'adapter'  => $validatorName,
       
  1253             'checksum' => false,
       
  1254         ));
       
  1255 
       
  1256         $checksumCharacter = '';
       
  1257         $withChecksum = false;
       
  1258         if ($this->_mandatoryChecksum) {
       
  1259             $checksumCharacter = $this->_substituteChecksumCharacter;
       
  1260             $withChecksum = true;
       
  1261         }
       
  1262 
       
  1263         $value = $this->_addLeadingZeros($value, $withChecksum) . $checksumCharacter;
       
  1264 
       
  1265         if (!$validator->isValid($value)) {
       
  1266             $message = implode("\n", $validator->getMessages());
       
  1267 
       
  1268             /**
       
  1269              * @see Zend_Barcode_Object_Exception
       
  1270              */
       
  1271             require_once 'Zend/Barcode/Object/Exception.php';
       
  1272             throw new Zend_Barcode_Object_Exception($message);
       
  1273         }
       
  1274     }
       
  1275 
       
  1276     /**
       
  1277      * Each child must prepare the barcode and return
       
  1278      * a table like array(
       
  1279      *     0 => array(
       
  1280      *         0 => int (visible(black) or not(white))
       
  1281      *         1 => int (width of the bar)
       
  1282      *         2 => float (0->1 position from the top of the beginning of the bar in %)
       
  1283      *         3 => float (0->1 position from the top of the end of the bar in %)
       
  1284      *     ),
       
  1285      *     1 => ...
       
  1286      * )
       
  1287      *
       
  1288      * @return array
       
  1289      */
       
  1290     abstract protected function _prepareBarcode();
       
  1291 
       
  1292     /**
       
  1293      * Checking of parameters after all settings
       
  1294      *
       
  1295      * @return void
       
  1296      */
       
  1297     abstract protected function _checkParams();
       
  1298 
       
  1299     /**
       
  1300      * Allow each child to draw something else
       
  1301      *
       
  1302      * @return void
       
  1303      */
       
  1304     protected function _preDrawBarcode()
       
  1305     {
       
  1306     }
       
  1307 
       
  1308     /**
       
  1309      * Allow each child to draw something else
       
  1310      * (ex: bearer bars in interleaved 2 of 5 code)
       
  1311      *
       
  1312      * @return void
       
  1313      */
       
  1314     protected function _postDrawBarcode()
       
  1315     {
       
  1316     }
       
  1317 }